library(tidyverse)
library(cowplot)
library(lubridate)
library(mgcv)
source("UVP_2017_library.R")
theme_set(theme_cowplot())
cb10 <- c('#a6cee3','#1f78b4','#b2df8a','#33a02c','#fb9a99','#e31a1c','#fdbf6f','#ff7f00','#cab2d6','#6a3d9a')

Particles Only

Read In Data

bes<- read_csv("dataOut/binned_EachSize.csv")
Parsed with column specification:
cols(
  .default = col_double(),
  project = col_character(),
  profile = col_character(),
  time = col_datetime(format = "")
)
See spec(...) for full column specifications.
bds <- read_csv("dataOut/binned_DepthSummary.csv")
Parsed with column specification:
cols(
  .default = col_double(),
  project = col_character(),
  profile = col_character(),
  time = col_datetime(format = "")
)
See spec(...) for full column specifications.
ues <- read_csv("dataOut/unbinned_EachSize.csv")
Parsed with column specification:
cols(
  project = col_character(),
  profile = col_character(),
  time = col_datetime(format = ""),
  depth = col_double(),
  psd_gam = col_double(),
  vol = col_double(),
  sizeclass = col_character(),
  lb = col_double(),
  ub = col_double(),
  binsize = col_double(),
  TotalParticles = col_double(),
  nparticles = col_double(),
  n_nparticles = col_double(),
  biovolume = col_double(),
  speed = col_double(),
  flux = col_double(),
  flux_fit = col_double(),
  GamPredictTP = col_double()
)
uds <- read_csv("dataOut/unbinned_DepthSummary.csv")
Parsed with column specification:
cols(
  .default = col_double(),
  project = col_character(),
  profile = col_character(),
  time = col_datetime(format = "")
)
See spec(...) for full column specifications.
PhoticBase <- 160
OMZBase <- 850

Summary Statistics

PlotNParticles <- uds %>% 
  ggplot(aes(x = tot_nparticles, y = depth, col = profile)) +
 facet_wrap(~project) +
 geom_point(alpha = 0.3, shape = 1) +
scale_y_reverse() + scale_x_log10()

PlotNParticles

bdsAddTime <- bds %>%
  mutate(Hour = hour(time), Day = day(time))

FSG1 <- gam(tot_nparticles~ s(depth, k = 3) + s(Day, k = 3) + s(Hour, k = 4, bs = "cc"), knots = list(Hour = c(0, 24)), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))

FSG2 <- gam(tot_nparticles ~ s(depth, k = 3) + s(Day, k = 3), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))

FSG3 <- gam(tot_nparticles ~ s(depth, k = 3), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))

#FSG4 <- gam(tot_nparticles~ s(depth, k = 3)  + s(Hour, k = 4, bs = "cc"), knots = list(Hour = c(0, 24)), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))

summary(FSG1)

Family: gaussian 
Link function: identity 

Formula:
tot_nparticles ~ s(depth, k = 3) + s(Day, k = 3) + s(Hour, k = 4, 
    bs = "cc")

Parametric coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)   9.0025     0.1091   82.55   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
            edf Ref.df     F p-value  
s(depth) 1.1031  1.196 3.873  0.0583 .
s(Day)   1.5509  1.796 3.715  0.0801 .
s(Hour)  0.4267  2.000 0.281  0.2713  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

R-sq.(adj) =  0.134   Deviance explained = 17.9%
GCV = 0.76575  Scale est. = 0.71367   n = 60
#summary(FSG2)
#summary(FSG3)
#summary(FSG4)

summary(FSG1)$r.sq - summary(FSG2)$r.sq
[1] 0.006778976
summary(FSG2)$r.sq - summary(FSG3)$r.sq
[1] 0.07324885
summary(FSG3)$r.sq
[1] 0.0542546

But there is between projects:

ProjGam <- gam(tot_nparticles~ s(depth, k = 3) + factor(project), knots = list(Hour = c(0, 24)), data = bdsAddTime %>% filter(depth >= 175 & depth <=500))

summary(ProjGam)

Family: gaussian 
Link function: identity 

Formula:
tot_nparticles ~ s(depth, k = 3) + factor(project)

Parametric coefficients:
                   Estimate Std. Error t value Pr(>|t|)    
(Intercept)          8.9983     0.4445   20.24   <2e-16 ***
factor(project)P16  17.0001     1.3754   12.36   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
         edf Ref.df     F p-value  
s(depth)   1      1 3.552   0.064 .
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

R-sq.(adj) =    0.7   Deviance explained = 70.9%
GCV = 12.411  Scale est. = 11.855    n = 67
library(scales)
#https://stackoverflow.com/questions/30179442/plotting-minor-breaks-on-a-log-scale-with-ggplot
log_breaks = function(maj, radix=10) {
  function(x) {
    minx         = floor(min(logb(x,radix), na.rm=T)) - 1
    maxx         = ceiling(max(logb(x,radix), na.rm=T)) + 1
    n_major      = maxx - minx + 1
    major_breaks = seq(minx, maxx, by=1)
    if (maj) {
      breaks = major_breaks
    } else {
      steps = logb(1:(radix-1),radix)
      breaks = rep(steps, times=n_major) +
               rep(major_breaks, each=radix-1)
    }
    radix^breaks
  }
}
scale_x_log_eng = function(..., radix=10) {
  scale_x_continuous(...,
                     trans=log_trans(radix),
                     breaks=log_breaks(TRUE, radix),
                     minor_breaks=log_breaks(FALSE, radix))
}

#theme_set(theme_bw)
PlotPSDmany <- uds %>% 
  filter(project == "ETNP") %>%
  ggplot(aes(x = psd, y = depth, shape = factor(day(time)), fill = hour(time))) +
 
  #geom_path(aes(x = psd_gam)) + 
  #geom_ribbon(aes(x = psd_gam, xmin = psd_gam - 2 * psd_seg, xmax = psd_gam + 2 * psd_seg), alpha = 0.1, outline_type = "lower") +
  geom_point(alpha = .6, size = 2, stroke = 1) +
  scale_y_reverse(limits = c(1200, 0)) + scale_shape_manual(values = c(21:25)) +
  scale_fill_gradientn(breaks = c(0, 6, 12, 18, 24), colors = c("black", "blue", "white", "orange", "black")) +
  labs(y = "Depth (m)", x = "Particle Size Distribution Slope") + 
  geom_hline(yintercept = 175, color = "darkgreen") +
  geom_hline(yintercept = 850, color = "darkblue") 

#theme_set(theme_cowplot)

PlotParticlesmany <- uds %>% 
  filter(project == "ETNP") %>%
  ggplot(aes(x = tot_nparticles, y = depth, shape = factor(day(time)), fill = hour(time))) +
 
  #geom_path(aes(x = psd_gam)) + 
  #geom_ribbon(aes(x = psd_gam, xmin = psd_gam - 2 * psd_seg, xmax = psd_gam + 2 * psd_seg), alpha = 0.1, outline_type = "lower") +
  geom_point(alpha = .6, size = 2, stroke = 1) +
  scale_y_reverse(limits = c(1200, 0)) + scale_shape_manual(values = c(21:25)) +
  scale_fill_gradientn(breaks = c(0, 6, 12, 18, 24), colors = c("black", "blue", "white", "orange", "black")) +
  scale_x_log10(breaks = c(10, 100, 1000), minor = c(5, 50, 500)) +
  #theme(legend.position = "none") +
  #scale_x_log_eng()+
  labs(y = "Depth (m)", x = "Particles / L") + 
  geom_hline(yintercept = 175, color = "darkgreen") +
  geom_hline(yintercept = 850, color = "darkblue") 

# PlotFluxmany <- uds %>% 
#   filter(project == "ETNP") %>%
#   ggplot(aes(x = tot_flux_fit, y = depth, shape = factor(day(time)), fill = hour(time))) +
#  
#   #geom_path(aes(x = psd_gam)) + 
#   #geom_ribbon(aes(x = psd_gam, xmin = psd_gam - 2 * psd_seg, xmax = psd_gam + 2 * psd_seg), alpha = 0.1, outline_type = "lower") +
#   geom_point(alpha = .6, size = 2, stroke = 1) +
#   scale_y_reverse() + scale_shape_manual(values = c(21:25)) +
#   scale_fill_gradientn(breaks = c(0, 6, 12, 18, 24), colors = c("black", "blue", "white", "orange", "black")) +
#   scale_x_log10() + theme(legend.position = "none")



plot_grid(
  PlotParticlesmany,
  PlotPSDmany,
  rel_widths = c(2, 3)
  )
Removed 266 rows containing missing values (geom_point).Removed 266 rows containing missing values (geom_point).

ggsave("figures/ParticlesPSDMany.png")
Saving 12 x 7.41 in image
ggsave("figures/ParticlesPSDMany.svg")
Saving 12 x 7.41 in image
bdsAddTime <- bds %>%
  mutate(Hour = hour(time), Day = day(time))

FSG1 <- gam(psd~ s(depth, k = 3) + s(Day, k = 3) + s(Hour, k = 4, bs = "cc"), knots = list(Hour = c(0, 24)), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))

FSG2 <- gam(psd ~ s(depth, k = 3) + s(Day, k = 3), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))

FSG3 <- gam(psd ~ s(depth, k = 3), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))

FSG4 <- gam(psd~ s(depth, k = 3)  + s(Hour, k = 4, bs = "cc"), knots = list(Hour = c(0, 24)), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))

summary(FSG1)

Family: gaussian 
Link function: identity 

Formula:
psd ~ s(depth, k = 3) + s(Day, k = 3) + s(Hour, k = 4, bs = "cc")

Parametric coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) -3.96083    0.01975  -200.6   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
           edf Ref.df      F  p-value    
s(depth) 1.719  1.921 56.605 3.83e-15 ***
s(Day)   1.000  1.000  1.278   0.2631    
s(Hour)  1.547  2.000  2.763   0.0347 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

R-sq.(adj) =  0.639   Deviance explained = 66.5%
GCV = 0.025652  Scale est. = 0.023401  n = 60
#summary(FSG2)
#summary(FSG3)
summary(FSG4)

Family: gaussian 
Link function: identity 

Formula:
psd ~ s(depth, k = 3) + s(Hour, k = 4, bs = "cc")

Parametric coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) -3.96083    0.01978  -200.3   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
           edf Ref.df      F  p-value    
s(depth) 1.721  1.922 56.019 4.39e-15 ***
s(Hour)  1.609  2.000  3.023   0.0294 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

R-sq.(adj) =  0.638   Deviance explained = 65.9%
GCV = 0.025297  Scale est. = 0.023471  n = 60
summary(FSG1)$r.sq - summary(FSG2)$r.sq
[1] 0.03439091
summary(FSG2)$r.sq - summary(FSG3)$r.sq
[1] 0.003377312
summary(FSG3)$r.sq
[1] 0.6015425

Not a significant difference in PSD with respect to time.

But there is between projects:

ProjGam <- gam(psd~ s(depth, k = 3) + factor(project), knots = list(Hour = c(0, 24)), data = bdsAddTime %>% filter(depth >= 175 & depth <=500))

summary(ProjGam)

Family: gaussian 
Link function: identity 

Formula:
psd ~ s(depth, k = 3) + factor(project)

Parametric coefficients:
                   Estimate Std. Error  t value Pr(>|t|)    
(Intercept)        -3.96167    0.02491 -159.029   <2e-16 ***
factor(project)P16 -0.19977    0.07708   -2.592   0.0118 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
           edf Ref.df     F  p-value    
s(depth) 1.224  1.398 34.54 2.26e-08 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

R-sq.(adj) =  0.437   Deviance explained = 45.6%
GCV = 0.039117  Scale est. = 0.037234  n = 67

I wonder if I can show that the profiles aren’t statistically significanlty different. Or that they are for that matter… I think in that case, I run a gam with and without a parameter for profile… And then quantify the effect size of that parameter

Or follow this Gavin Simpson Post https://fromthebottomoftheheap.net/2017/10/10/difference-splines-i/

or anova.gam {mgcv}

Calculate gams for each profile, and then run anova.gam to see if they are different…

PlotNParticlesEP <- uds %>% 
  filter(profile %in% c("stn_043", "p16n_100")) %>%
  ggplot(aes(x = tot_nparticles, y = depth, col = project, shape = project)) +
 geom_point(alpha = 0.7, size = 2, stroke = 1) +
  #geom_path(aes(x = tot_nparticles)) +
  #geom_ribbon(aes(x = psd_gam, xmin = psd_gam - 2 * psd_seg, xmax = psd_gam + 2 * psd_seg), alpha = 0.1) +
scale_y_reverse(limits = c(1000, 0)) + scale_x_log10() + scale_color_manual(values = c("gray20", "brown")) +
  labs(x = "Particles/L", y = "Depth (m)") +
  theme(legend.position = "none") +
  scale_shape_manual(values = c(1:5)) +
  geom_hline(yintercept = 175, color = "darkgreen") +
  geom_hline(yintercept = 200, color = "darkgreen") +
  geom_hline(yintercept = 850, color = "darkblue") 

PlotNParticlesEP

I removed one outlyer from p16 for visualization purposes (300 particles/l at surface)

PlotPSDEP <- uds %>% 
  filter(profile %in% c("stn_043", "p16n_100")) %>%
  ggplot(aes(x = psd, y = depth, col = project, shape = project)) +
 geom_point(alpha = 0.7, size = 2, stroke = 1) +
  geom_path(aes(x = psd_gam)) +
  geom_ribbon(aes(x = psd_gam, xmin = psd_gam - 2 * psd_seg, xmax = psd_gam + 2 * psd_seg), alpha = 0.1) +
scale_y_reverse(limits = c(1000, 0)) + scale_color_manual(values = c("gray20", "brown"))  +
  scale_shape_manual(values = c(1:5)) + labs(y = "", x = "Particle Size Distribution Slope") +
  geom_hline(yintercept = 175, color = "darkgreen") +
  geom_hline(yintercept = 200, color = "darkgreen") +
  geom_hline(yintercept = 850, color = "darkblue") 

PlotPSDEP

I may just cow these togther.

plot_grid(PlotNParticlesEP, PlotPSDEP, rel_widths = c(2,3), labels = c("A", "B"))
Removed 1211 rows containing missing values (geom_point).Removed 1211 rows containing missing values (geom_point).Removed 1211 row(s) containing missing values (geom_path).

ggsave("figures/ParticlesAndPSD_ETNPVsP16.svg")
Saving 10 x 4 in image
ggsave("figures/ParticlesAndPSD_ETNPVsP16.png")
Saving 10 x 4 in image
mainParticleComponents <- bds %>%
  filter(profile %in% c("stn_043", "p16n_100")) %>%
  select(project, profile, depth,
         tot_nparticles, small_nparticles, big_nparticles,
         tot_psd = psd, small_psd, big_psd,
         tot_flux_fit, small_flux_fit, big_flux_fit) %>%
  pivot_longer(cols = -c("project", "profile", "depth")) %>%
  separate(name, c("size", "meas")) %>%
  mutate(meas = recode(meas, nparticles = "particles/L")) %>%
  mutate(meas = factor(meas, levels = c("particles/L", "flux", "psd")))
Expected 2 pieces. Additional pieces discarded in 273 rows [7, 8, 9, 16, 17, 18, 25, 26, 27, 34, 35, 36, 43, 44, 45, 52, 53, 54, 61, 62, ...].
PlotFlx <- mainParticleComponents %>% 
  filter(meas != "psd") %>%
  ggplot(aes(y = depth, x = value, col = project, shape = project)) + facet_grid(size ~ meas, scales = "free_x") + geom_point(size = 2) + scale_y_reverse(limits = c(1000, 0)) + scale_x_log10() + theme(axis.title.x = element_blank(), legend.position = "none", strip.background.y = element_blank(), strip.text.y = element_blank(), plot.margin = unit(c(7,0,7,7), "pt")) + scale_color_manual(values = c("brown", "gray20")) + scale_shape_manual(values = c(1:5)) + theme(axis.text.x = element_text(angle = 90)) + geom_hline(yintercept = 175, color = "darkgreen")

PlotPSD <- mainParticleComponents %>% 
  filter(meas == "psd") %>%
  ggplot(aes(y = depth, x = value, col = project, shape = project)) + facet_grid(size~meas, scales = "free_x") + geom_point(size = 2) + scale_y_reverse(limits = c(1000, 0)) +
  theme(axis.title.x = element_blank(), axis.title.y = element_blank(), axis.line.y = element_blank(), axis.text.y = element_blank(), axis.ticks.y = element_blank(), plot.margin = unit(c(7,7,26.5,0), "pt")) +
  scale_color_manual(values = c("brown", "gray20")) +  scale_shape_manual(values = c(1:5)) +  theme(axis.text.x = element_text(angle = 90)) + geom_hline(yintercept = 175, color = "darkgreen")

plot_grid(PlotFlx, PlotPSD, rel_widths = c(3, 2))
Removed 246 rows containing missing values (geom_point).Removed 123 rows containing missing values (geom_point).
ggsave("figures/BigVsSmall.svg")
Saving 7.29 x 4.5 in image
ggsave("figures/BigVsSmall.png")
Saving 7.29 x 4.5 in image

Flux small and flux tot track so closely because ag > psd. since the size distribution of the flux sould be PSD + ag (psd is negative in this case). Yo ucan see the variance at the one depth where psd is flatest at the very top.

eg_dataline <- bds %>% 
  filter(profile == "stn_043", depth == 162.5)
eg_slope =  eg_dataline %>% pull(psd)
eg_icp = eg_dataline %>% pull(icp)
eg_vol = eg_dataline %>% pull(vol)

eg_datablock <- bes %>%
  filter(profile == "stn_043", depth == 162.5)


eg_lb = eg_datablock$lb
eg_binsize = eg_datablock$binsize
eg_nnp = exp(eg_icp + log(eg_lb) * eg_slope)

eg_np = eg_nnp * eg_binsize
eg_tp = eg_np * eg_vol
eg_df <- tibble(lb = eg_lb, n_nparticles = eg_nnp, nparticles = eg_np, TotalParticles = eg_tp)


EgNNP <- eg_datablock %>%
  ggplot(aes(x = lb, y = n_nparticles)) + geom_point() + scale_x_log10() + scale_y_log10() + 
  geom_path(data = eg_df) + labs(y = "Binsize & Volume Normalized \n Particles (#/L/mm)", x = "Size (mm)")

EgNP <- eg_datablock %>%
  ggplot(aes(x = lb, y = nparticles)) + geom_point() + scale_x_log10() + scale_y_log10() + 
  geom_path(data = eg_df) + labs(y = "Normalized Particles" , x = "Size (mm)")

EgTP <- eg_datablock %>%
  ggplot(aes(x = lb, y = TotalParticles)) + geom_point() + scale_x_log10() + scale_y_log10() + 
  geom_path(data = eg_df) + labs( y = "Total Particles Observed (#)", x = "Size (mm)")

plot_grid(EgNNP, EgTP, labels = c("A", "B"))
Transformation introduced infinite values in continuous y-axisTransformation introduced infinite values in continuous y-axis
ggsave("figures/ExamplePSD163m.png")
Saving 7.29 x 4.5 in image
ggsave("figures/ExamplePSD163m.svg")
Saving 7.29 x 4.5 in image

Smooth flux and um disaggregation.

bds %>% 
  ggplot(aes(y = depth, x = Flux_Smooth, col = factor(time))) + facet_wrap(~project) + geom_point() + scale_y_reverse(limits = c(1000, 0)) + scale_x_log10()

bdsAddTime <- bds %>%
  mutate(Hour = hour(time), Day = day(time))

FSG1 <- gam(Flux_Smooth~ s(depth, k = 3) + s(Day, k = 3) + s(Hour, k = 4, bs = "cc"), knots = list(Hour = c(0, 24)), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))

FSG2 <- gam(Flux_Smooth ~ s(depth, k = 3) + s(Day, k = 3), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))

FSG3 <- gam(Flux_Smooth ~ s(depth, k = 3), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))

summary(FSG1)

Family: gaussian 
Link function: identity 

Formula:
Flux_Smooth ~ s(depth, k = 3) + s(Day, k = 3) + s(Hour, k = 4, 
    bs = "cc")

Parametric coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  34.7319     0.9312    37.3   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
           edf Ref.df      F  p-value    
s(depth) 1.874  1.984 12.034 0.000111 ***
s(Day)   1.828  1.969  2.774 0.089781 .  
s(Hour)  1.515  2.000  2.784 0.031360 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

R-sq.(adj) =  0.333   Deviance explained = 39.2%
GCV = 58.038  Scale est. = 52.024    n = 60
summary(FSG2)

Family: gaussian 
Link function: identity 

Formula:
Flux_Smooth ~ s(depth, k = 3) + s(Day, k = 3)

Parametric coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  34.7319     0.9774   35.53   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
           edf Ref.df      F  p-value    
s(depth) 1.864  1.981 10.835 0.000255 ***
s(Day)   1.737  1.931  1.586 0.243284    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

R-sq.(adj) =  0.265   Deviance explained =   31%
GCV = 62.081  Scale est. = 57.32     n = 60
summary(FSG3)

Family: gaussian 
Link function: identity 

Formula:
Flux_Smooth ~ s(depth, k = 3)

Parametric coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  34.7319     0.9944   34.93   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
           edf Ref.df     F  p-value    
s(depth) 1.857  1.979 10.73 0.000277 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

R-sq.(adj) =  0.239   Deviance explained = 26.3%
GCV = 62.291  Scale est. = 59.325    n = 60
summary(FSG1)$r.sq - summary(FSG2)$r.sq
[1] 0.06791706
summary(FSG2)$r.sq - summary(FSG3)$r.sq
[1] 0.02571191
summary(FSG3)$r.sq
[1] 0.2392424
bds %>% filter(project == "ETNP") %>% select(profile, depth, Flux_Smooth) %>% pivot_wider(names_from = profile, values_from = Flux_Smooth)

Something is off. All of the flux profiles are identical. Skip this

cb10 <- c('#a6cee3','#1f78b4','#b2df8a','#33a02c','#fb9a99','#e31a1c','#fdbf6f','#ff7f00','#cab2d6','#6a3d9a')
plt1 <- bds %>% #filter(DFP > 1) %>% #filter(profile %in% c("stn_043", "p16n_100")) %>%
  ggplot(aes(y = depth, x = DFP, col = factor(time), shape = factor(time))) + facet_wrap(~project) + geom_point() + scale_y_reverse(limits = c(1000, 0)) + xlim(c(0.5, 1.5))+ geom_vline(xintercept = 1) +
   scale_color_manual(values = c(rep("black", 5), rep("blue", 5))) + scale_shape_manual(values = rep(1:5, 2))

plotly::ggplotly(plt1)

What the heck is going on with DFP here. Why is it usually > 1 shouldn’t it be less than 1 when flux is decreasing? This very deep increasing flux seems improbable to me. Lets check the smooths. Or only go to 1000m.

, legend.background = element_blank(), legend.box.background = element_rect()

scientific_10 <- function(x) {parse(text=gsub("e\\+*", " %*% 10^", scales::scientific_format()(x))) }
scientific_10_b <- function(x) {parse(text=gsub("e\\+*", " %*% 10^", scales::scientific_format()(x))) }

scientific_10_c <- function(x) {
    xout <- gsub("1e", "10^{", format(x),fixed=TRUE)
    xout <- gsub("{-0", "{-", xout,fixed=TRUE)
    xout <- gsub("{+", "{", xout,fixed=TRUE)
    xout <- gsub("{0", "{", xout,fixed=TRUE)
    xout <- paste(xout,"}",sep="")
    return(parse(text=xout))
    
}

scale_x_log10nice <- function(name=NULL,omag=seq(-10,20),...) {
    breaks10 <- 10^omag
    scale_x_log10(breaks=breaks10,labels=scientific_10_c(breaks10),...)
}


#https://stackoverflow.com/questions/10762287/how-can-i-format-axis-labels-with-exponents-with-ggplot2-and-scales
#jacob_magnitude <- function(x){expression(10^round(log10(x)))}

cb10 <- c('#a6cee3','#1f78b4','#b2df8a','#33a02c','#fb9a99','#e31a1c','#fdbf6f','#ff7f00','#cab2d6','#6a3d9a')
pltFlx <- bds %>% filter(project == "ETNP") %>% #filter(DFP > 1) %>% #filter(profile %in% c("stn_043", "p16n_100")) %>%
  ggplot(aes(y = depth, x = Flux_Smooth, shape = factor(day(time)), fill = hour(time), group = factor(time)))  + geom_point(size = 2, stroke = 1)+
  #geom_path() +
  scale_y_reverse(limits = c(1000, 0))+
  scale_x_log10nice()+
  #scale_x_log10() + 
   scale_color_gradient2(low = "darkgreen", mid = "gray80", high = "purple", midpoint = 10) + scale_shape_manual(name = "Day of Month", values = rep(21:25, 2)) + 
  scale_fill_gradientn(name = "Hour of Day", breaks = c(0, 6, 12, 18, 24), colors = c("black", "blue", "white", "orange", "black")) +
  
  labs(x = bquote(Smoothed~Flux~(µmol~C/m^2/d)), y = "Depth (m)") +
  #labs(x = "moo", y = "Depth (m)") +
  geom_rect(data = data.frame(project = "ETNP"), aes(xmin = 20, xmax = 180, ymin = 75, ymax = 500), colour = "red", fill = NA, inherit.aes = FALSE) +
  theme(axis.text.x = element_text(angle = 90, vjust = .3), legend.spacing = unit(.1, "cm")) +
   geom_segment(aes(y = 160, yend = 160, x = 20, xend = 500), color = "darkgreen", stroke = 0.5)+
   geom_segment(aes(y = 850, yend = 850, x = 20, xend = 500), color = "darkblue", stroke = 0.5)#+ geom_hline(yintercept = 850, color = "darkblue")
Ignoring unknown parameters: strokeIgnoring unknown parameters: stroke
pltFlxNoLegend <- pltFlx + theme(legend.position = "none")
pltFlxLegend <- get_legend(pltFlx)
Removed 14 rows containing missing values (geom_point).
pltFlx

#plotly::ggplotly(plt1)
cb10 <- c('#a6cee3','#1f78b4','#b2df8a','#33a02c','#fb9a99','#e31a1c','#fdbf6f','#ff7f00','#cab2d6','#6a3d9a')
pltFlxZoom <- bds %>% filter(project == "ETNP" & depth <= 500 & depth >= 75) %>% #filter(profile %in% c("stn_043", "p16n_100")) %>%
  ggplot(aes(y = depth, x = Flux_Smooth, shape = factor(day(time)), fill = hour(time), group = factor(time))) + geom_point(size = 2, stroke = 1)+
  #geom_path() +
  scale_y_reverse()+
  #scale_x_log10() +
  scale_x_log10(breaks = c(seq(from = 20, to = 50, by = 10), seq(from = 60, to = 180, by = 20)), limits = c(20, 180)) +
   scale_color_gradient2(low = "darkgreen", mid = "gray80", high = "purple", midpoint = 10) + scale_shape_manual(values = rep(21:25, 2)) + 
  scale_fill_gradientn(breaks = c(0, 6, 12, 18, 24), colors = c("black", "blue", "white", "orange", "black")) +
  theme(axis.text.x = element_text(angle = 90)) +
labs(x = "Smoothed Flux", y = "Depth") + theme(legend.position = "none")+
geom_hline(yintercept = 160, color = "darkgreen")

pltFlxZoom

#plotly::ggplotly(plt1)
cb10 <- c('#a6cee3','#1f78b4','#b2df8a','#33a02c','#fb9a99','#e31a1c','#fdbf6f','#ff7f00','#cab2d6','#6a3d9a')
pltDelta3 <- bds %>% filter(project == "ETNP") %>% #filter(DFP > 1) %>% #filter(profile %in% c("stn_043", "p16n_100")) %>%
  ggplot(aes(y = depth, x = pracma::nthroot(DF/DZ, 5), shape = factor(day(time)), fill = hour(time), group = factor(time)))  + geom_point(size = 2, stroke = 1)+
  #geom_path() +
  scale_y_reverse(limits = c(1000, 0))+
  scale_x_continuous(limits = c(-2.1, .6), breaks = seq(from = -2, to = .75, by = 0.5)) +
  #scale_x_log10() +
   scale_color_gradient2(low = "darkgreen", mid = "gray80", high = "purple", midpoint = 10) + scale_shape_manual(name = "Day of Month", values = rep(21:25, 2)) + 
  scale_fill_gradientn(name = "Hour", breaks = c(0, 6, 12, 18, 24), colors = c("black", "blue", "white", "orange", "black")) +
  geom_vline(xintercept = 0) +
  labs(x = bquote((DF/DZ)^{1/5}~(µmolC/m^3/d)^{1/5}), y = "Depth (m)") + theme(legend.pos = "none")+
  geom_hline(yintercept = 160, color = "darkgreen") + geom_hline(yintercept = 850, color = "darkblue")
  #labs(x = "(DF/DZ) ^ 1/5 (µmol C/m^3/d) ^ 1/5")

pltDelta3

#plotly::ggplotly(plt1pos)
# #plot_grid(pltFlxNoLegend, pltFlxZoom, pltDelta3, pltFlxLegend)
# 
# pltFlxLegend <- get_legend(pltFlx + theme(legend.box.margin = margin(0, 0, 40, 10)))
# 
# pgTop <- plot_grid(pltFlxNoLegend, pltFlxZoom + theme(plot.margin = unit(c(1, 0, 3, 0), units = "cm")), rel_widths = c(2, 1), labels = c("A", "B"))
# pgBottom <- plot_grid(pltDelta3, pltFlxLegend , rel_widths = c(3, 1), labels = c("C", ""), label_size = 14)
# pgBoth <- plot_grid(pgTop, pgBottom, ncol = 1)
# 
# pgBoth
# 
# ggsave("figures/FluxDeepDive.png")
# ggsave("figures/FluxDeepDive.svg")

Within panel drawing

pgTop <- ggdraw(pltFlxNoLegend 
       ) +
  draw_plot(pltFlxZoom, .4, .25, .55, .60) +
  draw_plot_label(
    c("","B"),
    c(.05, 0.55),
    c(1, 0.85),
    size = 16
  )
Removed 14 rows containing missing values (geom_point).
pgTop

pgBottom <- plot_grid(pltDelta3, pltFlxLegend , rel_widths = c(3, 1), labels = c(“C”, ""), label_size = 14)

I don’t know whats going on below here

pgBottom <- pltDelta3  + geom_rect(aes(xmin = -2, xmax = -1.15, ymin = 170, ymax = 1000), colour = "gray50", fill = NA, inherit.aes = FALSE) + draw_plot(pltFlxLegend , -1.9, -575, .7)
pgBoth <- plot_grid(pgTop + theme(plot.margin = unit(c(0, 0, 0, 0), units = "cm")),
                    pgBottom + theme(plot.margin = unit(c(0, 0, 0, 0), units = "cm")),
                    ncol = 1, rel_heights = c(4, 4), labels = c("A", "C"), label_size = 16)
Removed 33 rows containing missing values (geom_point).
pgBoth


ggsave("figures/FluxDeepDive.png")
Saving 5 x 9 in image
ggsave("figures/FluxDeepDive.svg")
Saving 5 x 9 in image
# #plot_grid(pltFlxNoLegend, pltFlxZoom, pltDelta3, pltFlxLegend)
# 
# pltFlxLegend <- get_legend(pltFlx + theme(legend.box.margin = margin(0, 0, 40, 10)))
# 
# pgTop <- plot_grid(pltFlxNoLegend + ylim(c(1000, 0)), pltFlxZoom + theme(plot.margin = unit(c(1, 0, 3, 0), units = "cm")), rel_widths = c(2, 1), labels = c("A", "B"))
# pgBottom <- plot_grid(pltDelta3 + ylim(c(1000, 0)), pltFlxLegend , rel_widths = c(3, 1), labels = c("C", ""))
# pgBoth <- plot_grid(pgTop, pgBottom, ncol = 1)
# 
# pgBoth
# 
# #ggsave("figures/FluxShallowDive.png")
# #ggsave("figures/FluxShallowDive.svg")

Test for day to day and hourly variability in delta flux

bdsAddTime <- bds %>% 
  mutate(Hour = hour(time), Day = day(time))

DFG1 <- gam(pracma::nthroot(DF/DZ, 5)~ s(depth, k = 3) + s(Day, k = 3) + s(Hour, k = 4, bs = "cc"), knots = list(Hour = c(0, 24)), data = bdsAddTime %>% filter(depth >= 250 & depth <=500 & project == "ETNP"))

DFG2 <- gam(pracma::nthroot(DF/DZ, 5) ~ s(depth, k = 3) + s(Day, k = 3), data = bdsAddTime %>% filter(depth >= 250 & depth <=500 & project == "ETNP"))

DFG3 <- gam(pracma::nthroot(DF/DZ, 5) ~ s(depth, k = 3), data = bdsAddTime %>% filter(depth >= 250 & depth <=500 & project == "ETNP"))

summary(DFG1)

Family: gaussian 
Link function: identity 

Formula:
pracma::nthroot(DF/DZ, 5) ~ s(depth, k = 3) + s(Day, k = 3) + 
    s(Hour, k = 4, bs = "cc")

Parametric coefficients:
            Estimate Std. Error t value Pr(>|t|)   
(Intercept) -0.18385    0.05697  -3.227  0.00267 **
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
           edf Ref.df     F p-value   
s(depth) 1.716  1.919 4.652 0.03562 * 
s(Day)   1.931  1.995 6.788 0.00412 **
s(Hour)  1.555  2.000 3.247 0.02318 * 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

R-sq.(adj) =  0.328   Deviance explained = 41.3%
GCV = 0.15991  Scale est. = 0.1363    n = 42
summary(DFG2)

Family: gaussian 
Link function: identity 

Formula:
pracma::nthroot(DF/DZ, 5) ~ s(depth, k = 3) + s(Day, k = 3)

Parametric coefficients:
            Estimate Std. Error t value Pr(>|t|)   
(Intercept) -0.18385    0.06186  -2.972  0.00514 **
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
           edf Ref.df     F p-value  
s(depth) 1.641  1.871 3.599  0.0798 .
s(Day)   1.827  1.970 3.034  0.0463 *
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

R-sq.(adj) =  0.207   Deviance explained = 27.4%
GCV = 0.17984  Scale est. = 0.1607    n = 42
summary(DFG3)

Family: gaussian 
Link function: identity 

Formula:
pracma::nthroot(DF/DZ, 5) ~ s(depth, k = 3)

Parametric coefficients:
            Estimate Std. Error t value Pr(>|t|)   
(Intercept) -0.18385    0.06635  -2.771  0.00849 **
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
           edf Ref.df     F p-value
s(depth) 1.592  1.834 3.213   0.107

R-sq.(adj) =  0.0878   Deviance explained = 12.3%
GCV = 0.19707  Scale est. = 0.18491   n = 42
summary(DFG1)$r.sq - summary(DFG2)$r.sq
[1] 0.1204131
summary(DFG2)$r.sq - summary(DFG3)$r.sq
[1] 0.1193917
summary(DFG3)$r.sq
[1] 0.08782536

png(filename = “./figures/CombinedP2Info.png”, width = 10, height = 8, units = “in”, res = 200) StationInfoPlot() dev.off()

#plot.new()
FluxGamPlot <- function(){
  par(mfrow = c(2,2))
  plot(DFG1)
  mtext(expression(bold("C")), side = 3, line = 0, adj = 0, cex = 2)
  par(mfg = c(1,1))
  mtext(expression(bold("A")), side = 3, line = 0, adj = 0, cex = 2)
  par(mfg = c(1,2))
  mtext(expression(bold("B")), side = 3, line = 0, adj = 0, cex = 2)
}

FluxGamPlot()

png(filename = "./figures/FluxGamPlot.png", width = 10, height = 8, units = "in", res = 200)
FluxGamPlot()
dev.off()
png 
  2 

Check of actual data for hour

ggplot(data = bds %>% filter(depth >= 175, depth <= 500), aes(y = DF/DZ, x = hour(time), col = depth, group = depth)) + geom_point() + geom_line()

#Osps

(u mol C / m^3 / day)

disagFig <- bds %>% filter(project == "ETNP") %>%
  ggplot(aes(y = depth, x = pracma::nthroot(ospsDZ, 3), shape = factor(day(time)), fill = hour(time), group = factor(time))) + geom_point(size = 2) + scale_y_reverse(limits = c(1000, 0)) +
  scale_x_continuous(limits = c(-1, 1)) +
  geom_vline(xintercept = 0) +   scale_shape_manual(name = "Day of Month", values = rep(21:25, 2)) +
  #labs(x = bquote("Observed - Modeled Small Particle Flux"~(μmol/m^3/day)), y = "Depth (m)") +
  labs(x = paste("OSMS", expression((μmol/m^3/day)))) +
  scale_fill_gradientn(name = "Hour of Day", breaks = c(0, 6, 12, 18, 24), colors = c("black", "blue", "white", "orange", "black")) + geom_hline(yintercept = 175, color = "darkgreen") + geom_hline(yintercept = 850, color = "darkblue")
disagFig

#ggsave("..figures/FluxSizeShift.svg"

 ggsave("figures/FluxSizeShift.png")
Saving 6 x 4 in image
 ggsave("figures/FluxSizeShift.svg")
Saving 6 x 4 in image

Clara Fig

For NSF Proposal plot_grid( PlotParticlesmany, PlotPSDmany, rel_widths = c(2, 3) )


pgTop <- ggdraw(pltFlxNoLegend 
       ) +
  draw_plot(pltFlxZoom, .4, .25, .55, .60) +
  draw_plot_label(
    c("","D"),
    c(.05, 0.55),
    c(1, 0.85),
    size = 16
  )
Removed 14 rows containing missing values (geom_point).
pgCF <- plot_grid(PlotParticlesmany + ylim(c(1000, 0)),
                  PlotPSDmany + ylim(c(1000, 0)) +theme(legend.position = "none"),
                  pgTop + theme(plot.margin = unit(c(0, 0, 0, 0), units = "cm")),
                    disagFig + theme(plot.margin = unit(c(0, 0, .2, 0), units = "cm")),
                    ncol = 2, rel_heights = c(4, 4), labels = c("A", "B", "C", "E"), label_size = 16)
Scale for 'y' is already present. Adding another scale for 'y', which will replace the existing scale.
Scale for 'y' is already present. Adding another scale for 'y', which will replace the existing scale.
Removed 308 rows containing missing values (geom_point).Removed 308 rows containing missing values (geom_point).Removed 37 rows containing missing values (geom_point).
pgCF


ggsave("./figures/UVP_for_zoop_proposal.png", pgCF, width = 10, height = 8, units = "in")
bdsAddTime <- bds %>%
  mutate(Hour = hour(time), Day = day(time))

OZG1 <- gam(ospsDZ ~ s(depth, k = 3) + s(Day, k = 3) + s(Hour, k = 4, bs = "cc"), knots = list(Hour = c(0, 24)), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))

OZG2 <- gam(ospsDZ ~ s(depth, k = 3) + s(Day, k = 3), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))

OZG3 <- gam(ospsDZ ~ s(depth, k = 3), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))

summary(OZG1)

Family: gaussian 
Link function: identity 

Formula:
ospsDZ ~ s(depth, k = 3) + s(Day, k = 3) + s(Hour, k = 4, bs = "cc")

Parametric coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) 0.023796   0.002244    10.6 6.42e-15 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
            edf Ref.df     F  p-value    
s(depth) 1.9032  1.991 8.166 0.000545 ***
s(Day)   1.8673  1.982 4.932 0.015920 *  
s(Hour)  0.1508  2.000 0.080 0.345843    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

R-sq.(adj) =  0.304   Deviance explained = 35.1%
GCV = 0.00032912  Scale est. = 0.00030213  n = 60
summary(OZG2)

Family: gaussian 
Link function: identity 

Formula:
ospsDZ ~ s(depth, k = 3) + s(Day, k = 3)

Parametric coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) 0.023796   0.002247   10.59 6.54e-15 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
           edf Ref.df     F  p-value    
s(depth) 1.904  1.991 8.157 0.000549 ***
s(Day)   1.868  1.983 4.868 0.016638 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

R-sq.(adj) =  0.302   Deviance explained = 34.7%
GCV = 0.00032916  Scale est. = 0.00030298  n = 60
summary(OZG3)

Family: gaussian 
Link function: identity 

Formula:
ospsDZ ~ s(depth, k = 3)

Parametric coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)   0.0238     0.0024   9.916 5.03e-14 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
           edf Ref.df     F  p-value    
s(depth) 1.894  1.989 7.458 0.000924 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

R-sq.(adj) =  0.204   Deviance explained =   23%
GCV = 0.00036308  Scale est. = 0.00034556  n = 60
summary(OZG1)$r.sq - summary(OZG2)$r.sq
[1] 0.001957736
summary(OZG2)$r.sq - summary(OZG3)$r.sq
[1] 0.09804936
summary(OZG3)$r.sq
[1] 0.2043621
OSMSGamPlot <- function(){
  par(mfrow = c(1,2))
  plot(OZG2)
  mtext(expression(bold("B")), side = 3, line = 0, adj = 0, cex = 2)
  par(mfg = c(1,1))
  mtext(expression(bold("A")), side = 3, line = 0, adj = 0, cex = 2)
}

OSMSGamPlot()

png(filename = "./figures/OSMSGamPlot.png", width = 10, height = 6, units = "in", res = 200)
OSMSGamPlot()

dev.off()
png 
  2 

plot(OZG2)

bds %>% filter(project == "P16") %>%
  ggplot(aes(y = depth, x = ospsDZ)) + facet_wrap(~project) + geom_point() + scale_y_reverse(limits = c(500, 0)) + geom_vline(xintercept = 0)

Trap data

trapFlux3 <- read_csv("dataOut/fluxMS_distilled.csv")
Parsed with column specification:
cols(
  Class = col_character(),
  Depth = col_double(),
  TrapID = col_character(),
  TrapType = col_character(),
  SampleType = col_character(),
  C_flux = col_double(),
  C_flux_umol = col_double()
)
UVPFluxComb <- read_csv("dataOut/CombinedProfileFluxEst_DS.csv")
Parsed with column specification:
cols(
  depth = col_double(),
  Flux = col_double()
)
UVPFluxOE <- read_csv("dataOut/ObservedVsExpectedFlux.csv")
Parsed with column specification:
cols(
  depth = col_double(),
  tn_flux = col_double(),
  profile = col_character(),
  project = col_character(),
  time = col_character(),
  tot_flux2 = col_double()
)
trapFlux3
UVPFluxComb

fluxMS_distilled_toPlot <- trapFlux3 %>%
  mutate(SampleType = recode(SampleType, `plus.p` = "plus-particles", top = "top-collector"))

Remove traps where mass spec didn’t work correctly 2-17 150 1-12 73m 1-12 148 2-14 100 |(TrapID == “2-17” & Depth == 150)

fluxMS_distilled_toPlot2 <- fluxMS_distilled_toPlot %>%
 filter(!((TrapID == "1-12") | (TrapID == "2-14" & Depth == 100)|(TrapID == "2-17" & Depth == 150)))
fluxMS_distilled_toPlot2
UVPFluxComb %>%
  ggplot(aes(y = depth))  + scale_y_reverse(limits = c(1000, 0)) +
  scale_x_continuous(limits = c(0, 200)) +
  geom_point(aes(y = Depth, x = C_flux_umol, fill = SampleType, shape = TrapType),
             colour = "black", stroke = 1, size = 5, data = fluxMS_distilled_toPlot) +
  geom_point(aes(x = Flux), size = 3, shape = 21, color = "white", fill = "black") +
  geom_point(aes(x = -1, y = -1, size = "UVP")) + # dummy point for the legend
scale_shape_manual(values = c(25, 22))+
  scale_size_manual(values = 1, name = "") +
  ylab("Depth (m)") + xlab("Flux µmolC/m^2/day") +
  guides(fill = guide_legend(override.aes = list(shape = 21))) +
  scale_fill_viridis_d() +
  theme_cowplot() + 
  theme(
        legend.position = c(0.5, 0.4),
        legend.box.background = element_rect(color = "black", size = 0.5),
        legend.margin = margin(-10, 5, 10, 5)
  ) +
  geom_rect(data = data.frame(project = "ETNP"), aes(xmin = 15, xmax = 32, ymin = 45, ymax = 195), colour = "red", fill = NA, inherit.aes = FALSE)
 ggsave("figures/FittedFlux.png")
Saving 7.29 x 4.5 in image
 ggsave("figures/FittedFlux.svg")
Saving 7.29 x 4.5 in image

Traps where mass spec didn’t work.

UVPFluxPlot00 <- UVPFluxComb %>% 
  ggplot(aes(y = depth))  + scale_y_reverse(limits = c(1000, 0)) +
  scale_x_continuous(limits = c(0, 200)) +
  geom_point(aes(y = Depth, x = C_flux_umol, shape = TrapType, ID = TrapID),
             colour = "black", stroke = 1, size = 5, data = fluxMS_distilled_toPlot2) +
  geom_line(aes(x = Flux), size = 1, color = "black") +
  geom_point(aes(x = -1, y = -1, size = "UVP Estimate")) + # dummy point for the legend
  geom_point(aes(x = tot_flux2), size = 3, shape = 21, color = "white", fill = "black", data = UVPFluxOE) +
scale_shape_manual(values = c(25, 22))+
  scale_size_manual(values = 1, name = "") +
  ylab("Depth (m)") +
  #xlab(expression(Flux µmolC/m^2/day)) +
  xlab(expression(paste("x axis ", ring(A)^2))) +
  xlab(expression(paste("Flux (µmolC/", m^2, "/day)"))) +
  
  guides(fill = guide_legend(override.aes = list(shape = 21))) +
  theme_cowplot() + 
  theme(
        legend.position = c(0.5, 0.4),
        legend.box.background = element_rect(color = "black", size = 0.5),
        legend.margin = margin(-10, 5, 10, 5)
  ) 
Ignoring unknown aesthetics: ID
# UVPFluxPlot <- UVPFluxPlot00 +
#   geom_rect(data = data.frame(project = "ETNP"), aes(xmin = 15, xmax = 32, ymin = 45, ymax = 195), colour = "red", fill = NA, inherit.aes = FALSE)

UVPFluxPlot00

ggsave("figures/FittedFlux.png")
Saving 7.29 x 4.5 in image
ggsave("figures/FittedFlux.svg")
Saving 7.29 x 4.5 in image

Example particle size distribution

horizontalGamPlot <- dataGamHorizontal %>% ggplot(aes(x = resp_fit, y = depth, col = log(lb), group = lb)) + scale_y_reverse() + geom_point() + scale_x_log10(limits = c(10^-8, NA)) + scale_color_viridis_c() + geom_path() + geom_vline(xintercept = 1) + geom_vline(xintercept = 5) + geom_errorbar(aes(xmin = resp_lower, xmax = resp_upper), width = 10, alpha = 0.5)+ theme_bw()

TPPlot <- bes %>% filter(profile == "stn_043") %>% group_by(lb) %>% ggplot(aes(x = TotalParticles, y = depth, col = log(lb), group = lb)) + scale_y_reverse(limits = c(1000, 0)) + geom_point() + scale_x_log10() + scale_color_viridis_c() + geom_path() + geom_vline(xintercept = 1) + geom_vline(xintercept = 5) + labs(y = "Depth (m)", x = "TotalParticles Observed (#)")

nnpPlot <- bes %>% filter(profile == "stn_043") %>% group_by(lb) %>% ggplot(aes(x = n_nparticles, y = depth, col = log(lb), group = lb)) + scale_y_reverse(limits = c(1000, 0)) + geom_point() + scale_x_log10() + scale_color_viridis_c() + geom_path() + geom_vline(xintercept = 1) + geom_vline(xintercept = 5) + labs(y = "Depth (m)", x = "Binsize and Volume Normalized Particles (#/L/mm)")

FitPlot <- bes %>% filter(profile == "stn_043") %>% group_by(lb) %>% ggplot(aes(x = nnp_smooth, xmin = nnp_lower, xmax = nnp_upper, y = depth, col = log(lb), group = lb)) + scale_y_reverse(limits = c(1000, 0)) + geom_point() + scale_x_log10() + scale_color_viridis_c() + geom_path() + geom_vline(xintercept = 1) + geom_vline(xintercept = 5) + labs(y = "Depth (m)", x = "Smoothed - Normalized Particles (#/L/mm)") + geom_errorbar(width = 10, alpha = 0.5)

npLegend <- get_legend(FitPlot + theme(legend.box.margin = margin(0, 0, 40, 200)) + labs(col = expression(log[e](Size (mm)))))
Removed 325 rows containing missing values (geom_point).Removed 325 row(s) containing missing values (geom_path).
plot_grid(
  TPPlot + theme(legend.position = "none"),
  nnpPlot + theme(legend.position = "none"),
  npLegend ,
  FitPlot + theme(legend.position = "none")
)
Transformation introduced infinite values in continuous x-axisTransformation introduced infinite values in continuous x-axisRemoved 325 rows containing missing values (geom_point).Removed 325 row(s) containing missing values (geom_path).Transformation introduced infinite values in continuous x-axisTransformation introduced infinite values in continuous x-axisRemoved 325 rows containing missing values (geom_point).Removed 325 row(s) containing missing values (geom_path).Removed 325 rows containing missing values (geom_point).Removed 325 row(s) containing missing values (geom_path).

ggsave("figures/AllParticleSizes.svg")
Saving 10 x 6.18 in image
ggsave("figures/AllParticleSizes.png")
Saving 10 x 6.18 in image

Weber Bianchi Figs

SameGam <- gam(TotalParticles ~s(log(lb), log(depth), by = factor(time)), offset = log(vol * binsize), family = nb(),
    data = bes %>% filter(project == "ETNP"))
besE <- bes %>% filter(project == "ETNP")

lb_new <- exp(seq(from = log(0.1), to = log(2.1), by = 0.05))
ub_new <- lead(lb_new)
binsize_new <- ub_new - lb_new

lbbs <- tibble(lb = lb_new, ub = ub_new, binsize = binsize_new)

Expanded <- expand_grid(lb = exp(seq(from = log(0.1), to = log(2), by = 0.05)), depth = seq(from = 20, to = 2000, by = 20), time = as.factor(unique(besE$time))) %>% left_join(lbbs, by = "lb")

Pred <- exp(predict(SameGam, Expanded))
ToPlot <- bind_cols(Expanded, nnparticles = Pred) %>% mutate(time = as.character(time)) %>% mutate(nparticles = nnparticles * binsize)
ToPlot %>% filter(lb <= 2) %>%  ggplot(aes(x = lb, y = depth, fill = log10(nnparticles), z = log10(nnparticles))) + geom_tile() + scale_fill_viridis_c() + scale_y_reverse() + scale_x_log10()  + facet_wrap(~time) + geom_contour(color = "black")
meanBese <- ToPlot %>% filter(lb <= 2) %>% group_by(lb, depth) %>% summarize(nparticles = mean(nparticles), nnparticles = mean(nnparticles))

WBColorMap <- meanBese%>%
   ggplot(aes(x = lb, y = depth, fill = log10(nnparticles), z = log10(nnparticles))) + geom_tile() + scale_fill_viridis_c(name = "log10(number density \n (normalized))") + scale_y_reverse() + scale_x_log10() + geom_contour(color = "black") + geom_hline(yintercept = 160, color = "darkgreen") + geom_hline(yintercept = 850, color = "darkblue")
WBColorMap

Average of everything

#meanBese043 <- ToPlot %>% filter(lb <= 2, time == "2017-01-13 11:51:31")

meanBese%>%
   ggplot(aes(x = lb, y = depth, fill = log10(nnparticles), z = log10(nnparticles))) + geom_tile() + scale_fill_viridis_c() + scale_y_reverse() + scale_x_log10() + geom_contour(color = "black") + geom_hline(yintercept = 160, color = "darkgreen")

Just 043

mbGam <- meanBese %>% group_by(depth)  %>% nest() %>%
  mutate(mod = map(data, ~gam(log(nnparticles) ~ log(lb), family = gaussian(), data = .))) %>% 
  mutate(psd = map_dbl(mod, ~summary(.)$p.coeff[2]))
mbGam %>% ggplot(aes(x = psd, y = depth)) + geom_path() + scale_y_reverse() + geom_hline(yintercept = 160, color = "darkgreen") + geom_hline(yintercept =  850, color = "darkblue")

mbGam <- meanBese043 %>% group_by(depth) %>% nest() %>% mutate(mod = map(data, ~gam(log(nnparticles) ~ log(lb), family = gaussian(), data = .))) %>% mutate(psd = map_dbl(mod, ~summary(.)$p.coeff[2]))

pWBPSD <- mbGam %>% ggplot(aes(x = psd, y = depth)) + geom_path() + scale_y_reverse()  + geom_hline(yintercept = 160, color = "darkgreen") + geom_hline(yintercept =  850, color = "darkblue")
pWBPSD

Fig 5 WB

bds %>% filter(profile == “stn_043”, depth <= 2000) %>% ggplot(aes(x = psd_gam, xmin = psd_gam - psd_seg * 2, xmax = psd_gam + psd_seg * 2, y = depth)) + geom_path(size = 1) + scale_y_reverse() + geom_hline(yintercept = 175, color = “darkgreen”) + geom_hline(yintercept = 950, color = “darkblue”) + geom_ribbon(alpha = 0.2) + labs(x = “PSD slope”)

All of them

bds %>% filter(profile == "stn_043", depth <= 2000) %>% ggplot(aes(x = psd_gam, xmin = psd_gam - psd_seg * 2, xmax = psd_gam + psd_seg * 2, y = depth)) + geom_path(size = 1) + scale_y_reverse() + geom_hline(yintercept = 175, color = "darkgreen") + geom_hline(yintercept = 950, color = "darkblue") + geom_ribbon(alpha = 0.2) + labs(x = "PSD slope")

043 only

bds %>% filter(profile == "stn_043", depth <= 2000, depth > 175) %>% ggplot(aes(x = small_biovolume, y = depth)) + geom_path(size = 1) + scale_y_reverse() + geom_hline(yintercept = 175, color = "darkgreen") + geom_hline(yintercept = 950, color = "darkblue") + geom_point()
ubDf0 <- ToPlot %>% mutate(ubiomass = nparticles * lb ^ ag_global)
ubDf <- ubDf0 %>% group_by(time, depth) %>% summarize(ubiomass = sum(ubiomass)) %>% ungroup %>% group_by(depth)
photicBiomass <- ubDf %>% filter(depth <= 180, depth >= 160) %>% summarize(ubiomass = mean(ubiomass)) %>% pull(ubiomass)
ubDf <- ubDf %>% mutate(nbiomass = ubiomass/photicBiomass)
ubDf %>% ggplot(aes(x = nbiomass, y = depth , group = time, col = time)) + geom_path() + scale_y_reverse() + scale_x_continuous(limits = c(0,1))
ubDf <- ToPlot %>% mutate(ubiomass = nparticles * lb ^ ag_global) %>% group_by(time, depth) %>% summarize(ubiomass = sum(ubiomass)) %>% ungroup %>% group_by(depth)  %>% summarise(ubiomass = mean(ubiomass))
photicBiomass <- ubDf %>% filter(depth <= 180, depth >= 160) %>% summarize(ubiomass = mean(ubiomass)) %>% pull(ubiomass)
ubDf <- ubDf %>% mutate(nbiomass = ubiomass/photicBiomass)
ubDf %>% ggplot(aes(x = nbiomass, y = depth)) + geom_path() + scale_y_reverse() + scale_x_continuous(limits = c(0,1)) + geom_hline(yintercept = 175, color = "darkgreen")

Small particles biomass

PubDf <- ToPlot %>% mutate(ubiomass = nparticles * lb ^ ag_global) %>% filter(lb < 0.5) %>% group_by(time, depth) %>% summarize(ubiomass = sum(ubiomass)) %>% ungroup %>% group_by(depth)  %>% summarise(ubiomass = mean(ubiomass))
photicBiomass <- PubDf %>% filter(depth <= 165, depth >= 155) %>% summarize(ubiomass = mean(ubiomass)) %>% pull(ubiomass)
PubDf <- PubDf %>% mutate(nbiomass = ubiomass/photicBiomass)
pWBS <- PubDf %>% ggplot(aes(x = nbiomass, y = depth)) + geom_path() + scale_y_reverse() + scale_x_continuous(limits = c(0,1.2)) + geom_hline(yintercept = 160, color = "darkgreen") + geom_vline(xintercept = 1, color = "gray50") + geom_vline(xintercept = 0, color = "gray50") + geom_hline(yintercept = 850, color = "darkblue") + labs( x = "Small particle mass (norm.)")
pWBS
LubDf <- ToPlot %>% mutate(ubiomass = nparticles * lb ^ ag_global) %>% filter(lb >= 0.5) %>% group_by(time, depth) %>% summarize(ubiomass = sum(ubiomass)) %>% ungroup %>% group_by(depth)  %>% summarise(ubiomass = mean(ubiomass))
photicBiomass <- LubDf %>% filter(depth <= 165, depth >=155) %>% summarize(ubiomass = mean(ubiomass)) %>% pull(ubiomass)
LubDf <- LubDf %>% mutate(nbiomass = ubiomass/photicBiomass)
pWBL <- LubDf %>% ggplot(aes(x = nbiomass, y = depth)) + geom_path() + scale_y_reverse() + scale_x_continuous(limits = c(0,1)) + geom_hline(yintercept = 160, color = "darkgreen") + labs( x = "Large particle mass (norm.)") + geom_vline(xintercept = 1, color = "gray50") + geom_vline(xintercept = 0, color = "gray50") + geom_hline(yintercept = 850, color = "darkblue")
pWBL

For tom and danielle

WBColorMap
pWBPSD
pWBS
pWBL
WBFig5 <- plot_grid(pWBPSD, pWBS,pWBL, nrow = 1, labels = c("B", "C", "D"))
WBFig5
WBcombined <- plot_grid(WBColorMap + theme(plot.margin = unit(c(0,3,0, 3), "cm")), WBFig5, ncol = 1, labels = c("A", ""))
WBcombined

ggsave("figures/WBModelValidation.png")

P16 Flux

scientific_10 <- function(x) {parse(text=gsub("e\\+*", " %*% 10^", scales::scientific_format()(x))) }
#https://stackoverflow.com/questions/10762287/how-can-i-format-axis-labels-with-exponents-with-ggplot2-and-scales
#jacob_magnitude <- function(x){expression(10^round(log10(x)))}

cb10 <- c('#a6cee3','#1f78b4','#b2df8a','#33a02c','#fb9a99','#e31a1c','#fdbf6f','#ff7f00','#cab2d6','#6a3d9a')
pltFlxP16 <- bds %>% filter(project == "P16") %>% #filter(DFP > 1) %>% #filter(profile %in% c("stn_043", "p16n_100")) %>%
  ggplot(aes(y = depth, x = Flux_Smooth, group = factor(time)))  + geom_point(size = 3, stroke = 1)+
  geom_path() +
  scale_y_reverse(limits = c(1000, 0))+
  scale_x_log10(limits = c(35, 150),breaks = seq(from = 20, to = 150, by = 20)) +
   scale_color_gradient2(low = "darkgreen", mid = "gray80", high = "purple", midpoint = 10) + scale_shape_manual(name = "Day of Month", values = rep(21:25, 2)) + 
  scale_fill_gradientn(name = "Hour of Day", breaks = c(0, 6, 12, 18, 24), colors = c("black", "blue", "white", "orange", "black")) +
  
labs(x = bquote(Smoothed~Flux~(µmol~C/m^2/d)), y = "Depth (m)") +
  geom_hline(yintercept = 200, color = "darkgreen") +
  theme(axis.text.x = element_text(angle = 90, vjust = .3), legend.spacing = unit(.1, "cm"))
# 
# 
# 
# pltFlxNoLegend <- pltFlx + theme(legend.position = "none")
# pltFlxLegend <- get_legend(pltFlx)
# 
pltFlxP16
# #plotly::ggplotly(plt1)
cb10 <- c('#a6cee3','#1f78b4','#b2df8a','#33a02c','#fb9a99','#e31a1c','#fdbf6f','#ff7f00','#cab2d6','#6a3d9a')
pltDelta3P16 <- bds %>% filter(project == "P16") %>% #filter(DFP > 1) %>% #filter(profile %in% c("stn_043", "p16n_100")) %>%
  ggplot(aes(y = depth, x = pracma::nthroot(DF/DZ, 5), group = factor(time)))  + geom_point(size = 3, stroke = 1)+
  geom_path() +
  scale_y_reverse(limits = c(1000, 0))+
  scale_x_continuous(limits = c(-1, .1), breaks = seq(from = -2, to = .75, by = 0.5)) +
  #scale_x_log10() +
   scale_color_gradient2(low = "darkgreen", mid = "gray80", high = "purple", midpoint = 10) + scale_shape_manual(name = "Day of Month", values = rep(21:25, 2)) + 
  scale_fill_gradientn(name = "Hour", breaks = c(0, 6, 12, 18, 24), colors = c("black", "blue", "white", "orange", "black")) +
  geom_vline(xintercept = 0) +
  geom_hline(yintercept = 200, color = "darkgreen")+
  labs(x = bquote((DF/DZ)^{1/5}~(µmolC/m^3/d)^{1/5}), y = "Depth (m)") + theme(legend.pos = "none")
  #labs(x = "(DF/DZ) ^ 1/5 (µmol C/m^3/d) ^ 1/5")

pltDelta3P16
#plotly::ggplotly(plt1pos)
osms_p16 <- bds %>% filter(project == "P16") %>%
  ggplot(aes(y = depth, x = pracma::nthroot(ospsDZ, 3), group = factor(time))) + geom_point(size = 3) + geom_path() + scale_y_reverse(limits = c(1000, 0)) +
  scale_x_continuous(limits = c(-1, 1)) +
  geom_vline(xintercept = 0) +   scale_shape_manual(name = "Day of Month", values = rep(21:25, 2)) + labs(x = "Observed - Modeled Small Particle Flux \n µmol/m^3/day") +
  scale_fill_gradientn(name = "Hour of Day", breaks = c(0, 6, 12, 18, 24), colors = c("black", "blue", "white", "orange", "black")) + geom_hline(yintercept = 175, color = "darkgreen") 
plotly::ggplotly(osms_p16)
#ggsave("..figures/FluxSizeShift.svg"
plot_grid(
  pltFlxP16,
  pltDelta3P16,
  osms_p16
)

ggsave("figures/P16FluxRelate.svg")
ggsave("figures/P16FluxRelate.png")

Flux attenuation example

source("ModelStuff.R")
scan_for_example <- bds %>% filter(project == "ETNP", depth < 500, depth > 200) %>% select(profile, depth, DFP, use_this_DFP, ospsDZ)

loc_station = "stn_036"
loc_depth = 225
loc_prev_depth = loc_depth - 50

loc_DFP <- bds %>% filter(profile == loc_station, depth %in% c(275)) %>% pull(DFP)
loc_use_DFP <- bds %>% filter(profile == loc_station, depth %in% c(275)) %>% pull(use_this_DFP)
for_single_disag <- bes %>% filter(profile == loc_station, depth %in% c(225, 275)) %>% select(depth, lb, nnp_smooth) %>%
  mutate(depth = recode(depth, `225` = "Shallow", `275` = "Deep")) %>%
  pivot_wider(names_from = depth, values_from = nnp_smooth) 

with_disag <- for_single_disag %>%
  mutate(Predicted_Deep = remin_smooth_shuffle(Shallow, loc_use_DFP)) 
#remin_smooth_shuffle(for_single_disag$Shallow,loc_use_DFP)

for_plot_disag <- with_disag %>% pivot_longer(cols = -lb) %>% filter(lb <= 0.5) %>%
  mutate(name = factor(name, levels = c("Shallow", "Deep", "Predicted_Deep"))) %>%
  mutate(name = recode_factor(name, Shallow = "Shallow (250m)", Deep = "Deep (275m)", Predicted_Deep = "Predicted Deep (275m)"))

for_plot_disag %>% ggplot(aes(x = lb, y = value, shape = name)) + geom_point() + scale_x_log10() + scale_y_log10() + scale_shape_manual(values = c(1, 6, 3)) + theme(legend.title = element_blank()) + labs(x = "Particle Size (mm)", y = "Normalized Particle Abundance (#/L/mm)")

ggsave("figures/DisagExample.png")
ggsave("figures/DisagExample.svg")

EK60

dataBinned <- read_csv("data/backscatter_table_go7.csv")
dataBinned_01 <- dataBinned %>%
  mutate(timeMex = with_tz(time_bin, tzone = "US/Central") )
startDay <- dataBinned_01$timeMex %>% na.omit %>% min %>% floor_date(unit = "days")
endDay <- dataBinned_01$timeMex %>% na.omit %>% max %>% ceiling_date(unit = "days")
timeBreaks <- seq(from = startDay, to = endDay, by = "12 hours")
timeLabels <- format(timeBreaks)
plotLetters <- tribble(
  ~letter, ~depth_bin, ~timeMex,
  "A", 350, as.POSIXct("2017-01-07 13:00:00"),
  "B", 200, as.POSIXct("2017-01-09 23:00:00"),
  "C", 150, as.POSIXct("2017-01-08 13:00:00"),
  "D", 625, as.POSIXct("2017-01-12 07:00:00"),
  "E", 750, as.POSIXct("2017-01-10 02:00:00")
  
)

library(shadowtext)
plot18k <- dataBinned_01 %>% filter(frequency == 18000) %>% ggplot(aes(x = timeMex, y = depth_bin, fill = value)) + geom_tile() + scale_y_reverse() + scale_fill_viridis_c(limits = c(-165, -75), oob = scales::squish) +
  scale_x_datetime(breaks = timeBreaks, date_labels = "%d::%H") + labs(x = "day::hour", y = "depth (m)", fill = "backscatter (dB)") + theme_bw() + theme(axis.text.x = element_text(angle = 90, vjust = 0.5)) + geom_hline(yintercept = 160, color = "darkgreen") +
  geom_hline(yintercept = 850, color = "darkblue") +
  geom_shadowtext(data = plotLetters, aes(x = timeMex - 12 * 60^2, y = depth_bin, label = letter),  inherit.aes = FALSE, size = 6, bg.color = "white", color = "black") +
  geom_segment(data = plotLetters, inherit.aes = FALSE, aes(x = timeMex - 9 * 60^2, xend = timeMex, y = depth_bin, yend = depth_bin), arrow = arrow(length = unit(0.03, "npc")), color = "white", size = 1.5) + 
  geom_segment(data = plotLetters, inherit.aes = FALSE, aes(x = timeMex - 9 * 60^2, xend = timeMex, y = depth_bin, yend = depth_bin), arrow = arrow(length = unit(0.03, "npc")))
plot18k

#ggsave("figures/stationP2_EK60_18kOnly.png")
plotLetters <- tribble(
  ~letter, ~depth_bin, ~timeMex,
  "A", 300, as.POSIXct("2017-01-07 13:00:00"),
  "B", 200, as.POSIXct("2017-01-09 23:00:00"),
  "C", 150, as.POSIXct("2017-01-08 13:00:00"),
  "D", 625, as.POSIXct("2017-01-12 07:00:00"),
  "E", 750, as.POSIXct("2017-01-10 02:00:00")
  
)

library(shadowtext)
plot38k <- dataBinned_01 %>% filter(frequency == 38000) %>% ggplot(aes(x = timeMex, y = depth_bin, fill = value)) + geom_tile() + scale_y_reverse() + scale_fill_viridis_c(limits = c(-165, -95), oob = scales::squish) +
  scale_x_datetime(breaks = timeBreaks, date_labels = "%d::%H") + labs(x = "Day::Hour", y = "Depth (m)", fill = "Backscatter (dB)") + theme_bw()  + geom_hline(yintercept = 160, color = "darkgreen") +
  geom_hline(yintercept = 850, color = "darkblue") +
  geom_shadowtext(data = plotLetters[1:2,], aes(x = timeMex - 12 * 60^2, y = depth_bin, label = letter),  inherit.aes = FALSE, size = 6, bg.color = "white", color = "black") +
  geom_segment(data = plotLetters[1:2,], inherit.aes = FALSE, aes(x = timeMex - 9 * 60^2, xend = timeMex, y = depth_bin, yend = depth_bin), arrow = arrow(length = unit(0.03, "npc")), color = "white", size = 1.5) + 
  geom_segment(data = plotLetters[1:2,], inherit.aes = FALSE, aes(x = timeMex - 9 * 60^2, xend = timeMex, y = depth_bin, yend = depth_bin), arrow = arrow(length = unit(0.03, "npc"))) +
  theme(axis.text.x = element_text(size = 12,angle = 90, vjust = 0.5),
        axis.text.y = element_text(size = 12),
        axis.title = element_text(size = 14),
        legend.title = element_text(size = 14)
        )
plot38k

ggsave("figures/stationP2_EK60_38kOnly.png")
plot18k + scale_y_reverse(limits = c(500, 200))
plot200k <- dataBinned_01 %>% filter(frequency == 200000) %>% ggplot(aes(x = timeMex, y = depth_bin, fill = value)) + geom_tile() + scale_y_reverse() + scale_fill_viridis_c(limits = c(-165, -155), oob = scales::squish) +
  scale_x_datetime(breaks = timeBreaks, date_labels = "%d::%H") + labs(x = "day::hour", y = "depth (m)", fill = "backscatter (dB)") + theme_bw() + theme(axis.text.x = element_text(angle = 90, vjust = 0.5)) + geom_hline(yintercept = 160, color = "darkgreen") +
  geom_hline(yintercept = 850, color = "darkblue")
plot200k
dataBinned_01 %>% ggplot(aes(x = timeMex, y = depth_bin, fill = value)) + geom_tile() + scale_y_reverse() + scale_fill_viridis_c(limits = c(-165, -75), oob = scales::squish) +
  scale_x_datetime(breaks = timeBreaks, date_labels = "%d::%H") + labs(x = "day::hour", y = "Depth (m)", fill = "backscatter (dB)") + theme_bw() + theme(axis.text.x = element_text(angle = 90, vjust = 0.5)) +
  
  
  facet_wrap(~frequency, ncol = 1)


#ggsave("figures/stationP2_EK60_go7.svg", width = 4, height = 10)
ggsave("figures/stationP2_EK60_go7.png", width = 6, height = 10)
LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKYGBge3J9CmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KGNvd3Bsb3QpCmxpYnJhcnkobHVicmlkYXRlKQpsaWJyYXJ5KG1nY3YpCnNvdXJjZSgiVVZQXzIwMTdfbGlicmFyeS5SIikKdGhlbWVfc2V0KHRoZW1lX2Nvd3Bsb3QoKSkKY2IxMCA8LSBjKCcjYTZjZWUzJywnIzFmNzhiNCcsJyNiMmRmOGEnLCcjMzNhMDJjJywnI2ZiOWE5OScsJyNlMzFhMWMnLCcjZmRiZjZmJywnI2ZmN2YwMCcsJyNjYWIyZDYnLCcjNmEzZDlhJykKYGBgCgoKIyBQYXJ0aWNsZXMgT25seQoKIyBSZWFkIEluIERhdGEKCmBgYHtyfQpiZXM8LSByZWFkX2NzdigiZGF0YU91dC9iaW5uZWRfRWFjaFNpemUuY3N2IikKYmRzIDwtIHJlYWRfY3N2KCJkYXRhT3V0L2Jpbm5lZF9EZXB0aFN1bW1hcnkuY3N2IikKdWVzIDwtIHJlYWRfY3N2KCJkYXRhT3V0L3VuYmlubmVkX0VhY2hTaXplLmNzdiIpCnVkcyA8LSByZWFkX2NzdigiZGF0YU91dC91bmJpbm5lZF9EZXB0aFN1bW1hcnkuY3N2IikKYGBgCgpgYGB7cn0KUGhvdGljQmFzZSA8LSAxNjAKT01aQmFzZSA8LSA4NTAKYGBgCgoKIyBTdW1tYXJ5IFN0YXRpc3RpY3MKYGBge3J9ClBsb3ROUGFydGljbGVzIDwtIHVkcyAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gdG90X25wYXJ0aWNsZXMsIHkgPSBkZXB0aCwgY29sID0gcHJvZmlsZSkpICsKIGZhY2V0X3dyYXAofnByb2plY3QpICsKIGdlb21fcG9pbnQoYWxwaGEgPSAwLjMsIHNoYXBlID0gMSkgKwpzY2FsZV95X3JldmVyc2UoKSArIHNjYWxlX3hfbG9nMTAoKQoKUGxvdE5QYXJ0aWNsZXMKYGBgCgpgYGB7cn0KYmRzQWRkVGltZSA8LSBiZHMgJT4lCiAgbXV0YXRlKEhvdXIgPSBob3VyKHRpbWUpLCBEYXkgPSBkYXkodGltZSkpCgpGU0cxIDwtIGdhbSh0b3RfbnBhcnRpY2xlc34gcyhkZXB0aCwgayA9IDMpICsgcyhEYXksIGsgPSAzKSArIHMoSG91ciwgayA9IDQsIGJzID0gImNjIiksIGtub3RzID0gbGlzdChIb3VyID0gYygwLCAyNCkpLCBkYXRhID0gYmRzQWRkVGltZSAlPiUgZmlsdGVyKGRlcHRoID49IDE3NSAmIGRlcHRoIDw9NTAwICYgcHJvamVjdCA9PSAiRVROUCIpKQoKRlNHMiA8LSBnYW0odG90X25wYXJ0aWNsZXMgfiBzKGRlcHRoLCBrID0gMykgKyBzKERheSwgayA9IDMpLCBkYXRhID0gYmRzQWRkVGltZSAlPiUgZmlsdGVyKGRlcHRoID49IDE3NSAmIGRlcHRoIDw9NTAwICYgcHJvamVjdCA9PSAiRVROUCIpKQoKRlNHMyA8LSBnYW0odG90X25wYXJ0aWNsZXMgfiBzKGRlcHRoLCBrID0gMyksIGRhdGEgPSBiZHNBZGRUaW1lICU+JSBmaWx0ZXIoZGVwdGggPj0gMTc1ICYgZGVwdGggPD01MDAgJiBwcm9qZWN0ID09ICJFVE5QIikpCgojRlNHNCA8LSBnYW0odG90X25wYXJ0aWNsZXN+IHMoZGVwdGgsIGsgPSAzKSAgKyBzKEhvdXIsIGsgPSA0LCBicyA9ICJjYyIpLCBrbm90cyA9IGxpc3QoSG91ciA9IGMoMCwgMjQpKSwgZGF0YSA9IGJkc0FkZFRpbWUgJT4lIGZpbHRlcihkZXB0aCA+PSAxNzUgJiBkZXB0aCA8PTUwMCAmIHByb2plY3QgPT0gIkVUTlAiKSkKCnN1bW1hcnkoRlNHMSkKI3N1bW1hcnkoRlNHMikKI3N1bW1hcnkoRlNHMykKI3N1bW1hcnkoRlNHNCkKCnN1bW1hcnkoRlNHMSkkci5zcSAtIHN1bW1hcnkoRlNHMikkci5zcQpzdW1tYXJ5KEZTRzIpJHIuc3EgLSBzdW1tYXJ5KEZTRzMpJHIuc3EKc3VtbWFyeShGU0czKSRyLnNxCmBgYAoKQnV0IHRoZXJlIGlzIGJldHdlZW4gcHJvamVjdHM6CmBgYHtyfQpQcm9qR2FtIDwtIGdhbSh0b3RfbnBhcnRpY2xlc34gcyhkZXB0aCwgayA9IDMpICsgZmFjdG9yKHByb2plY3QpLCBrbm90cyA9IGxpc3QoSG91ciA9IGMoMCwgMjQpKSwgZGF0YSA9IGJkc0FkZFRpbWUgJT4lIGZpbHRlcihkZXB0aCA+PSAxNzUgJiBkZXB0aCA8PTUwMCkpCgpzdW1tYXJ5KFByb2pHYW0pCmBgYAoKYGBge3IgZmlnLndpZHRoID0gMTJ9CmxpYnJhcnkoc2NhbGVzKQojaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMzAxNzk0NDIvcGxvdHRpbmctbWlub3ItYnJlYWtzLW9uLWEtbG9nLXNjYWxlLXdpdGgtZ2dwbG90CmxvZ19icmVha3MgPSBmdW5jdGlvbihtYWosIHJhZGl4PTEwKSB7CiAgZnVuY3Rpb24oeCkgewogICAgbWlueCAgICAgICAgID0gZmxvb3IobWluKGxvZ2IoeCxyYWRpeCksIG5hLnJtPVQpKSAtIDEKICAgIG1heHggICAgICAgICA9IGNlaWxpbmcobWF4KGxvZ2IoeCxyYWRpeCksIG5hLnJtPVQpKSArIDEKICAgIG5fbWFqb3IgICAgICA9IG1heHggLSBtaW54ICsgMQogICAgbWFqb3JfYnJlYWtzID0gc2VxKG1pbngsIG1heHgsIGJ5PTEpCiAgICBpZiAobWFqKSB7CiAgICAgIGJyZWFrcyA9IG1ham9yX2JyZWFrcwogICAgfSBlbHNlIHsKICAgICAgc3RlcHMgPSBsb2diKDE6KHJhZGl4LTEpLHJhZGl4KQogICAgICBicmVha3MgPSByZXAoc3RlcHMsIHRpbWVzPW5fbWFqb3IpICsKICAgICAgICAgICAgICAgcmVwKG1ham9yX2JyZWFrcywgZWFjaD1yYWRpeC0xKQogICAgfQogICAgcmFkaXheYnJlYWtzCiAgfQp9CnNjYWxlX3hfbG9nX2VuZyA9IGZ1bmN0aW9uKC4uLiwgcmFkaXg9MTApIHsKICBzY2FsZV94X2NvbnRpbnVvdXMoLi4uLAogICAgICAgICAgICAgICAgICAgICB0cmFucz1sb2dfdHJhbnMocmFkaXgpLAogICAgICAgICAgICAgICAgICAgICBicmVha3M9bG9nX2JyZWFrcyhUUlVFLCByYWRpeCksCiAgICAgICAgICAgICAgICAgICAgIG1pbm9yX2JyZWFrcz1sb2dfYnJlYWtzKEZBTFNFLCByYWRpeCkpCn0KCiN0aGVtZV9zZXQodGhlbWVfYncpClBsb3RQU0RtYW55IDwtIHVkcyAlPiUgCiAgZmlsdGVyKHByb2plY3QgPT0gIkVUTlAiKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBwc2QsIHkgPSBkZXB0aCwgc2hhcGUgPSBmYWN0b3IoZGF5KHRpbWUpKSwgZmlsbCA9IGhvdXIodGltZSkpKSArCiAKICAjZ2VvbV9wYXRoKGFlcyh4ID0gcHNkX2dhbSkpICsgCiAgI2dlb21fcmliYm9uKGFlcyh4ID0gcHNkX2dhbSwgeG1pbiA9IHBzZF9nYW0gLSAyICogcHNkX3NlZywgeG1heCA9IHBzZF9nYW0gKyAyICogcHNkX3NlZyksIGFscGhhID0gMC4xLCBvdXRsaW5lX3R5cGUgPSAibG93ZXIiKSArCiAgZ2VvbV9wb2ludChhbHBoYSA9IC42LCBzaXplID0gMiwgc3Ryb2tlID0gMSkgKwogIHNjYWxlX3lfcmV2ZXJzZShsaW1pdHMgPSBjKDEyMDAsIDApKSArIHNjYWxlX3NoYXBlX21hbnVhbCh2YWx1ZXMgPSBjKDIxOjI1KSkgKwogIHNjYWxlX2ZpbGxfZ3JhZGllbnRuKGJyZWFrcyA9IGMoMCwgNiwgMTIsIDE4LCAyNCksIGNvbG9ycyA9IGMoImJsYWNrIiwgImJsdWUiLCAid2hpdGUiLCAib3JhbmdlIiwgImJsYWNrIikpICsKICBsYWJzKHkgPSAiRGVwdGggKG0pIiwgeCA9ICJQYXJ0aWNsZSBTaXplIERpc3RyaWJ1dGlvbiBTbG9wZSIpICsgCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMTc1LCBjb2xvciA9ICJkYXJrZ3JlZW4iKSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gODUwLCBjb2xvciA9ICJkYXJrYmx1ZSIpIAoKI3RoZW1lX3NldCh0aGVtZV9jb3dwbG90KQoKUGxvdFBhcnRpY2xlc21hbnkgPC0gdWRzICU+JSAKICBmaWx0ZXIocHJvamVjdCA9PSAiRVROUCIpICU+JQogIGdncGxvdChhZXMoeCA9IHRvdF9ucGFydGljbGVzLCB5ID0gZGVwdGgsIHNoYXBlID0gZmFjdG9yKGRheSh0aW1lKSksIGZpbGwgPSBob3VyKHRpbWUpKSkgKwogCiAgI2dlb21fcGF0aChhZXMoeCA9IHBzZF9nYW0pKSArIAogICNnZW9tX3JpYmJvbihhZXMoeCA9IHBzZF9nYW0sIHhtaW4gPSBwc2RfZ2FtIC0gMiAqIHBzZF9zZWcsIHhtYXggPSBwc2RfZ2FtICsgMiAqIHBzZF9zZWcpLCBhbHBoYSA9IDAuMSwgb3V0bGluZV90eXBlID0gImxvd2VyIikgKwogIGdlb21fcG9pbnQoYWxwaGEgPSAuNiwgc2l6ZSA9IDIsIHN0cm9rZSA9IDEpICsKICBzY2FsZV95X3JldmVyc2UobGltaXRzID0gYygxMjAwLCAwKSkgKyBzY2FsZV9zaGFwZV9tYW51YWwodmFsdWVzID0gYygyMToyNSkpICsKICBzY2FsZV9maWxsX2dyYWRpZW50bihicmVha3MgPSBjKDAsIDYsIDEyLCAxOCwgMjQpLCBjb2xvcnMgPSBjKCJibGFjayIsICJibHVlIiwgIndoaXRlIiwgIm9yYW5nZSIsICJibGFjayIpKSArCiAgc2NhbGVfeF9sb2cxMChicmVha3MgPSBjKDEwLCAxMDAsIDEwMDApLCBtaW5vciA9IGMoNSwgNTAsIDUwMCkpICsKICAjdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArCiAgI3NjYWxlX3hfbG9nX2VuZygpKwogIGxhYnMoeSA9ICJEZXB0aCAobSkiLCB4ID0gIlBhcnRpY2xlcyAvIEwiKSArIAogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDE3NSwgY29sb3IgPSAiZGFya2dyZWVuIikgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDg1MCwgY29sb3IgPSAiZGFya2JsdWUiKSAKCiMgUGxvdEZsdXhtYW55IDwtIHVkcyAlPiUgCiMgICBmaWx0ZXIocHJvamVjdCA9PSAiRVROUCIpICU+JQojICAgZ2dwbG90KGFlcyh4ID0gdG90X2ZsdXhfZml0LCB5ID0gZGVwdGgsIHNoYXBlID0gZmFjdG9yKGRheSh0aW1lKSksIGZpbGwgPSBob3VyKHRpbWUpKSkgKwojICAKIyAgICNnZW9tX3BhdGgoYWVzKHggPSBwc2RfZ2FtKSkgKyAKIyAgICNnZW9tX3JpYmJvbihhZXMoeCA9IHBzZF9nYW0sIHhtaW4gPSBwc2RfZ2FtIC0gMiAqIHBzZF9zZWcsIHhtYXggPSBwc2RfZ2FtICsgMiAqIHBzZF9zZWcpLCBhbHBoYSA9IDAuMSwgb3V0bGluZV90eXBlID0gImxvd2VyIikgKwojICAgZ2VvbV9wb2ludChhbHBoYSA9IC42LCBzaXplID0gMiwgc3Ryb2tlID0gMSkgKwojICAgc2NhbGVfeV9yZXZlcnNlKCkgKyBzY2FsZV9zaGFwZV9tYW51YWwodmFsdWVzID0gYygyMToyNSkpICsKIyAgIHNjYWxlX2ZpbGxfZ3JhZGllbnRuKGJyZWFrcyA9IGMoMCwgNiwgMTIsIDE4LCAyNCksIGNvbG9ycyA9IGMoImJsYWNrIiwgImJsdWUiLCAid2hpdGUiLCAib3JhbmdlIiwgImJsYWNrIikpICsKIyAgIHNjYWxlX3hfbG9nMTAoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikKCgoKcGxvdF9ncmlkKAogIFBsb3RQYXJ0aWNsZXNtYW55LAogIFBsb3RQU0RtYW55LAogIHJlbF93aWR0aHMgPSBjKDIsIDMpCiAgKQoKZ2dzYXZlKCJmaWd1cmVzL1BhcnRpY2xlc1BTRE1hbnkucG5nIikKZ2dzYXZlKCJmaWd1cmVzL1BhcnRpY2xlc1BTRE1hbnkuc3ZnIikKCmBgYAoKYGBge3J9CmJkc0FkZFRpbWUgPC0gYmRzICU+JQogIG11dGF0ZShIb3VyID0gaG91cih0aW1lKSwgRGF5ID0gZGF5KHRpbWUpKQoKRlNHMSA8LSBnYW0ocHNkfiBzKGRlcHRoLCBrID0gMykgKyBzKERheSwgayA9IDMpICsgcyhIb3VyLCBrID0gNCwgYnMgPSAiY2MiKSwga25vdHMgPSBsaXN0KEhvdXIgPSBjKDAsIDI0KSksIGRhdGEgPSBiZHNBZGRUaW1lICU+JSBmaWx0ZXIoZGVwdGggPj0gMTc1ICYgZGVwdGggPD01MDAgJiBwcm9qZWN0ID09ICJFVE5QIikpCgpGU0cyIDwtIGdhbShwc2QgfiBzKGRlcHRoLCBrID0gMykgKyBzKERheSwgayA9IDMpLCBkYXRhID0gYmRzQWRkVGltZSAlPiUgZmlsdGVyKGRlcHRoID49IDE3NSAmIGRlcHRoIDw9NTAwICYgcHJvamVjdCA9PSAiRVROUCIpKQoKRlNHMyA8LSBnYW0ocHNkIH4gcyhkZXB0aCwgayA9IDMpLCBkYXRhID0gYmRzQWRkVGltZSAlPiUgZmlsdGVyKGRlcHRoID49IDE3NSAmIGRlcHRoIDw9NTAwICYgcHJvamVjdCA9PSAiRVROUCIpKQoKRlNHNCA8LSBnYW0ocHNkfiBzKGRlcHRoLCBrID0gMykgICsgcyhIb3VyLCBrID0gNCwgYnMgPSAiY2MiKSwga25vdHMgPSBsaXN0KEhvdXIgPSBjKDAsIDI0KSksIGRhdGEgPSBiZHNBZGRUaW1lICU+JSBmaWx0ZXIoZGVwdGggPj0gMTc1ICYgZGVwdGggPD01MDAgJiBwcm9qZWN0ID09ICJFVE5QIikpCgpzdW1tYXJ5KEZTRzEpCiNzdW1tYXJ5KEZTRzIpCiNzdW1tYXJ5KEZTRzMpCnN1bW1hcnkoRlNHNCkKCnN1bW1hcnkoRlNHMSkkci5zcSAtIHN1bW1hcnkoRlNHMikkci5zcQpzdW1tYXJ5KEZTRzIpJHIuc3EgLSBzdW1tYXJ5KEZTRzMpJHIuc3EKc3VtbWFyeShGU0czKSRyLnNxCmBgYApOb3QgYSBzaWduaWZpY2FudCBkaWZmZXJlbmNlIGluIFBTRCB3aXRoIHJlc3BlY3QgdG8gdGltZS4KCkJ1dCB0aGVyZSBpcyBiZXR3ZWVuIHByb2plY3RzOgpgYGB7cn0KUHJvakdhbSA8LSBnYW0ocHNkfiBzKGRlcHRoLCBrID0gMykgKyBmYWN0b3IocHJvamVjdCksIGtub3RzID0gbGlzdChIb3VyID0gYygwLCAyNCkpLCBkYXRhID0gYmRzQWRkVGltZSAlPiUgZmlsdGVyKGRlcHRoID49IDE3NSAmIGRlcHRoIDw9NTAwKSkKCnN1bW1hcnkoUHJvakdhbSkKYGBgCgoKCgpJIHdvbmRlciBpZiBJIGNhbiBzaG93IHRoYXQgdGhlIHByb2ZpbGVzIGFyZW4ndCBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW5sdHkgZGlmZmVyZW50LiBPciB0aGF0IHRoZXkgYXJlIGZvciB0aGF0IG1hdHRlci4uLgpJIHRoaW5rIGluIHRoYXQgY2FzZSwgSSBydW4gYSBnYW0gd2l0aCBhbmQgd2l0aG91dCBhIHBhcmFtZXRlciBmb3IgcHJvZmlsZS4uLgpBbmQgdGhlbiBxdWFudGlmeSB0aGUgZWZmZWN0IHNpemUgb2YgdGhhdCBwYXJhbWV0ZXIKCk9yIGZvbGxvdyB0aGlzIEdhdmluIFNpbXBzb24gUG9zdApodHRwczovL2Zyb210aGVib3R0b21vZnRoZWhlYXAubmV0LzIwMTcvMTAvMTAvZGlmZmVyZW5jZS1zcGxpbmVzLWkvCgpvciAKYW5vdmEuZ2FtIHttZ2N2fQoKQ2FsY3VsYXRlIGdhbXMgZm9yIGVhY2ggcHJvZmlsZSwgYW5kIHRoZW4gcnVuIGFub3ZhLmdhbSB0byBzZWUgaWYgdGhleSBhcmUgZGlmZmVyZW50Li4uCgpgYGB7cn0KUGxvdE5QYXJ0aWNsZXNFUCA8LSB1ZHMgJT4lIAogIGZpbHRlcihwcm9maWxlICVpbiUgYygic3RuXzA0MyIsICJwMTZuXzEwMCIpKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSB0b3RfbnBhcnRpY2xlcywgeSA9IGRlcHRoLCBjb2wgPSBwcm9qZWN0LCBzaGFwZSA9IHByb2plY3QpKSArCiBnZW9tX3BvaW50KGFscGhhID0gMC43LCBzaXplID0gMiwgc3Ryb2tlID0gMSkgKwogICNnZW9tX3BhdGgoYWVzKHggPSB0b3RfbnBhcnRpY2xlcykpICsKICAjZ2VvbV9yaWJib24oYWVzKHggPSBwc2RfZ2FtLCB4bWluID0gcHNkX2dhbSAtIDIgKiBwc2Rfc2VnLCB4bWF4ID0gcHNkX2dhbSArIDIgKiBwc2Rfc2VnKSwgYWxwaGEgPSAwLjEpICsKc2NhbGVfeV9yZXZlcnNlKGxpbWl0cyA9IGMoMTAwMCwgMCkpICsgc2NhbGVfeF9sb2cxMCgpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoImdyYXkyMCIsICJicm93biIpKSArCiAgbGFicyh4ID0gIlBhcnRpY2xlcy9MIiwgeSA9ICJEZXB0aCAobSkiKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArCiAgc2NhbGVfc2hhcGVfbWFudWFsKHZhbHVlcyA9IGMoMTo1KSkgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDE3NSwgY29sb3IgPSAiZGFya2dyZWVuIikgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDIwMCwgY29sb3IgPSAiZGFya2dyZWVuIikgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDg1MCwgY29sb3IgPSAiZGFya2JsdWUiKSAKClBsb3ROUGFydGljbGVzRVAKYGBgCgpJIHJlbW92ZWQgb25lIG91dGx5ZXIgZnJvbSBwMTYgZm9yIHZpc3VhbGl6YXRpb24gcHVycG9zZXMgKDMwMCBwYXJ0aWNsZXMvbCBhdCBzdXJmYWNlKQoKYGBge3J9ClBsb3RQU0RFUCA8LSB1ZHMgJT4lIAogIGZpbHRlcihwcm9maWxlICVpbiUgYygic3RuXzA0MyIsICJwMTZuXzEwMCIpKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBwc2QsIHkgPSBkZXB0aCwgY29sID0gcHJvamVjdCwgc2hhcGUgPSBwcm9qZWN0KSkgKwogZ2VvbV9wb2ludChhbHBoYSA9IDAuNywgc2l6ZSA9IDIsIHN0cm9rZSA9IDEpICsKICBnZW9tX3BhdGgoYWVzKHggPSBwc2RfZ2FtKSkgKwogIGdlb21fcmliYm9uKGFlcyh4ID0gcHNkX2dhbSwgeG1pbiA9IHBzZF9nYW0gLSAyICogcHNkX3NlZywgeG1heCA9IHBzZF9nYW0gKyAyICogcHNkX3NlZyksIGFscGhhID0gMC4xKSArCnNjYWxlX3lfcmV2ZXJzZShsaW1pdHMgPSBjKDEwMDAsIDApKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCJncmF5MjAiLCAiYnJvd24iKSkgICsKICBzY2FsZV9zaGFwZV9tYW51YWwodmFsdWVzID0gYygxOjUpKSArIGxhYnMoeSA9ICIiLCB4ID0gIlBhcnRpY2xlIFNpemUgRGlzdHJpYnV0aW9uIFNsb3BlIikgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDE3NSwgY29sb3IgPSAiZGFya2dyZWVuIikgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDIwMCwgY29sb3IgPSAiZGFya2dyZWVuIikgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDg1MCwgY29sb3IgPSAiZGFya2JsdWUiKSAKClBsb3RQU0RFUApgYGAKCkkgbWF5IGp1c3QgY293IHRoZXNlIHRvZ3RoZXIuCgpgYGB7ciBmaWcud2lkdGggPSAxMCwgZmlnLmhlaWdodCA9IDR9CnBsb3RfZ3JpZChQbG90TlBhcnRpY2xlc0VQLCBQbG90UFNERVAsIHJlbF93aWR0aHMgPSBjKDIsMyksIGxhYmVscyA9IGMoIkEiLCAiQiIpKQpnZ3NhdmUoImZpZ3VyZXMvUGFydGljbGVzQW5kUFNEX0VUTlBWc1AxNi5zdmciKQpnZ3NhdmUoImZpZ3VyZXMvUGFydGljbGVzQW5kUFNEX0VUTlBWc1AxNi5wbmciKQpgYGAKCmBgYHtyfQptYWluUGFydGljbGVDb21wb25lbnRzIDwtIGJkcyAlPiUKICBmaWx0ZXIocHJvZmlsZSAlaW4lIGMoInN0bl8wNDMiLCAicDE2bl8xMDAiKSkgJT4lCiAgc2VsZWN0KHByb2plY3QsIHByb2ZpbGUsIGRlcHRoLAogICAgICAgICB0b3RfbnBhcnRpY2xlcywgc21hbGxfbnBhcnRpY2xlcywgYmlnX25wYXJ0aWNsZXMsCiAgICAgICAgIHRvdF9wc2QgPSBwc2QsIHNtYWxsX3BzZCwgYmlnX3BzZCwKICAgICAgICAgdG90X2ZsdXhfZml0LCBzbWFsbF9mbHV4X2ZpdCwgYmlnX2ZsdXhfZml0KSAlPiUKICBwaXZvdF9sb25nZXIoY29scyA9IC1jKCJwcm9qZWN0IiwgInByb2ZpbGUiLCAiZGVwdGgiKSkgJT4lCiAgc2VwYXJhdGUobmFtZSwgYygic2l6ZSIsICJtZWFzIikpICU+JQogIG11dGF0ZShtZWFzID0gcmVjb2RlKG1lYXMsIG5wYXJ0aWNsZXMgPSAicGFydGljbGVzL0wiKSkgJT4lCiAgbXV0YXRlKG1lYXMgPSBmYWN0b3IobWVhcywgbGV2ZWxzID0gYygicGFydGljbGVzL0wiLCAiZmx1eCIsICJwc2QiKSkpCgpQbG90Rmx4IDwtIG1haW5QYXJ0aWNsZUNvbXBvbmVudHMgJT4lIAogIGZpbHRlcihtZWFzICE9ICJwc2QiKSAlPiUKICBnZ3Bsb3QoYWVzKHkgPSBkZXB0aCwgeCA9IHZhbHVlLCBjb2wgPSBwcm9qZWN0LCBzaGFwZSA9IHByb2plY3QpKSArIGZhY2V0X2dyaWQoc2l6ZSB+IG1lYXMsIHNjYWxlcyA9ICJmcmVlX3giKSArIGdlb21fcG9pbnQoc2l6ZSA9IDIpICsgc2NhbGVfeV9yZXZlcnNlKGxpbWl0cyA9IGMoMTAwMCwgMCkpICsgc2NhbGVfeF9sb2cxMCgpICsgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLCBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsIHN0cmlwLmJhY2tncm91bmQueSA9IGVsZW1lbnRfYmxhbmsoKSwgc3RyaXAudGV4dC55ID0gZWxlbWVudF9ibGFuaygpLCBwbG90Lm1hcmdpbiA9IHVuaXQoYyg3LDAsNyw3KSwgInB0IikpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoImJyb3duIiwgImdyYXkyMCIpKSArIHNjYWxlX3NoYXBlX21hbnVhbCh2YWx1ZXMgPSBjKDE6NSkpICsgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpICsgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMTc1LCBjb2xvciA9ICJkYXJrZ3JlZW4iKQoKUGxvdFBTRCA8LSBtYWluUGFydGljbGVDb21wb25lbnRzICU+JSAKICBmaWx0ZXIobWVhcyA9PSAicHNkIikgJT4lCiAgZ2dwbG90KGFlcyh5ID0gZGVwdGgsIHggPSB2YWx1ZSwgY29sID0gcHJvamVjdCwgc2hhcGUgPSBwcm9qZWN0KSkgKyBmYWNldF9ncmlkKHNpemV+bWVhcywgc2NhbGVzID0gImZyZWVfeCIpICsgZ2VvbV9wb2ludChzaXplID0gMikgKyBzY2FsZV95X3JldmVyc2UobGltaXRzID0gYygxMDAwLCAwKSkgKwogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy50aXRsZS55ID0gZWxlbWVudF9ibGFuaygpLCBheGlzLmxpbmUueSA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy50ZXh0LnkgPSBlbGVtZW50X2JsYW5rKCksIGF4aXMudGlja3MueSA9IGVsZW1lbnRfYmxhbmsoKSwgcGxvdC5tYXJnaW4gPSB1bml0KGMoNyw3LDI2LjUsMCksICJwdCIpKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoImJyb3duIiwgImdyYXkyMCIpKSArICBzY2FsZV9zaGFwZV9tYW51YWwodmFsdWVzID0gYygxOjUpKSArICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkgKyBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAxNzUsIGNvbG9yID0gImRhcmtncmVlbiIpCgpwbG90X2dyaWQoUGxvdEZseCwgUGxvdFBTRCwgcmVsX3dpZHRocyA9IGMoMywgMikpCgpnZ3NhdmUoImZpZ3VyZXMvQmlnVnNTbWFsbC5zdmciKQpnZ3NhdmUoImZpZ3VyZXMvQmlnVnNTbWFsbC5wbmciKQpgYGAKCkZsdXggc21hbGwgYW5kIGZsdXggdG90IHRyYWNrIHNvIGNsb3NlbHkgYmVjYXVzZSBhZyA+IHBzZC4gc2luY2UgdGhlIHNpemUgZGlzdHJpYnV0aW9uIG9mIHRoZSBmbHV4IHNvdWxkIGJlIFBTRCArIGFnIChwc2QgaXMgbmVnYXRpdmUgaW4gdGhpcyBjYXNlKS4gWW8gdWNhbiBzZWUgdGhlIHZhcmlhbmNlIGF0IHRoZSBvbmUgZGVwdGggd2hlcmUgcHNkIGlzIGZsYXRlc3QgYXQgdGhlIHZlcnkgdG9wLgoKYGBge3J9CmVnX2RhdGFsaW5lIDwtIGJkcyAlPiUgCiAgZmlsdGVyKHByb2ZpbGUgPT0gInN0bl8wNDMiLCBkZXB0aCA9PSAxNjIuNSkKZWdfc2xvcGUgPSAgZWdfZGF0YWxpbmUgJT4lIHB1bGwocHNkKQplZ19pY3AgPSBlZ19kYXRhbGluZSAlPiUgcHVsbChpY3ApCmVnX3ZvbCA9IGVnX2RhdGFsaW5lICU+JSBwdWxsKHZvbCkKCmVnX2RhdGFibG9jayA8LSBiZXMgJT4lCiAgZmlsdGVyKHByb2ZpbGUgPT0gInN0bl8wNDMiLCBkZXB0aCA9PSAxNjIuNSkKCgplZ19sYiA9IGVnX2RhdGFibG9jayRsYgplZ19iaW5zaXplID0gZWdfZGF0YWJsb2NrJGJpbnNpemUKZWdfbm5wID0gZXhwKGVnX2ljcCArIGxvZyhlZ19sYikgKiBlZ19zbG9wZSkKCmVnX25wID0gZWdfbm5wICogZWdfYmluc2l6ZQplZ190cCA9IGVnX25wICogZWdfdm9sCmVnX2RmIDwtIHRpYmJsZShsYiA9IGVnX2xiLCBuX25wYXJ0aWNsZXMgPSBlZ19ubnAsIG5wYXJ0aWNsZXMgPSBlZ19ucCwgVG90YWxQYXJ0aWNsZXMgPSBlZ190cCkKCgpFZ05OUCA8LSBlZ19kYXRhYmxvY2sgJT4lCiAgZ2dwbG90KGFlcyh4ID0gbGIsIHkgPSBuX25wYXJ0aWNsZXMpKSArIGdlb21fcG9pbnQoKSArIHNjYWxlX3hfbG9nMTAoKSArIHNjYWxlX3lfbG9nMTAoKSArIAogIGdlb21fcGF0aChkYXRhID0gZWdfZGYpICsgbGFicyh5ID0gIkJpbnNpemUgJiBWb2x1bWUgTm9ybWFsaXplZCBcbiBQYXJ0aWNsZXMgKCMvTC9tbSkiLCB4ID0gIlNpemUgKG1tKSIpCgpFZ05QIDwtIGVnX2RhdGFibG9jayAlPiUKICBnZ3Bsb3QoYWVzKHggPSBsYiwgeSA9IG5wYXJ0aWNsZXMpKSArIGdlb21fcG9pbnQoKSArIHNjYWxlX3hfbG9nMTAoKSArIHNjYWxlX3lfbG9nMTAoKSArIAogIGdlb21fcGF0aChkYXRhID0gZWdfZGYpICsgbGFicyh5ID0gIk5vcm1hbGl6ZWQgUGFydGljbGVzIiAsIHggPSAiU2l6ZSAobW0pIikKCkVnVFAgPC0gZWdfZGF0YWJsb2NrICU+JQogIGdncGxvdChhZXMoeCA9IGxiLCB5ID0gVG90YWxQYXJ0aWNsZXMpKSArIGdlb21fcG9pbnQoKSArIHNjYWxlX3hfbG9nMTAoKSArIHNjYWxlX3lfbG9nMTAoKSArIAogIGdlb21fcGF0aChkYXRhID0gZWdfZGYpICsgbGFicyggeSA9ICJUb3RhbCBQYXJ0aWNsZXMgT2JzZXJ2ZWQgKCMpIiwgeCA9ICJTaXplIChtbSkiKQoKcGxvdF9ncmlkKEVnTk5QLCBFZ1RQLCBsYWJlbHMgPSBjKCJBIiwgIkIiKSkKZ2dzYXZlKCJmaWd1cmVzL0V4YW1wbGVQU0QxNjNtLnBuZyIpCmdnc2F2ZSgiZmlndXJlcy9FeGFtcGxlUFNEMTYzbS5zdmciKQoKYGBgCgojIFNtb290aCBmbHV4IGFuZCB1bSBkaXNhZ2dyZWdhdGlvbi4KCmBgYHtyfQpiZHMgJT4lIAogIGdncGxvdChhZXMoeSA9IGRlcHRoLCB4ID0gRmx1eF9TbW9vdGgsIGNvbCA9IGZhY3Rvcih0aW1lKSkpICsgZmFjZXRfd3JhcCh+cHJvamVjdCkgKyBnZW9tX3BvaW50KCkgKyBzY2FsZV95X3JldmVyc2UobGltaXRzID0gYygxMDAwLCAwKSkgKyBzY2FsZV94X2xvZzEwKCkKYGBgCgoKCgpgYGB7cn0KYmRzQWRkVGltZSA8LSBiZHMgJT4lCiAgbXV0YXRlKEhvdXIgPSBob3VyKHRpbWUpLCBEYXkgPSBkYXkodGltZSkpCgpGU0cxIDwtIGdhbShGbHV4X1Ntb290aH4gcyhkZXB0aCwgayA9IDMpICsgcyhEYXksIGsgPSAzKSArIHMoSG91ciwgayA9IDQsIGJzID0gImNjIiksIGtub3RzID0gbGlzdChIb3VyID0gYygwLCAyNCkpLCBkYXRhID0gYmRzQWRkVGltZSAlPiUgZmlsdGVyKGRlcHRoID49IDE3NSAmIGRlcHRoIDw9NTAwICYgcHJvamVjdCA9PSAiRVROUCIpKQoKRlNHMiA8LSBnYW0oRmx1eF9TbW9vdGggfiBzKGRlcHRoLCBrID0gMykgKyBzKERheSwgayA9IDMpLCBkYXRhID0gYmRzQWRkVGltZSAlPiUgZmlsdGVyKGRlcHRoID49IDE3NSAmIGRlcHRoIDw9NTAwICYgcHJvamVjdCA9PSAiRVROUCIpKQoKRlNHMyA8LSBnYW0oRmx1eF9TbW9vdGggfiBzKGRlcHRoLCBrID0gMyksIGRhdGEgPSBiZHNBZGRUaW1lICU+JSBmaWx0ZXIoZGVwdGggPj0gMTc1ICYgZGVwdGggPD01MDAgJiBwcm9qZWN0ID09ICJFVE5QIikpCgpzdW1tYXJ5KEZTRzEpCnN1bW1hcnkoRlNHMikKc3VtbWFyeShGU0czKQoKc3VtbWFyeShGU0cxKSRyLnNxIC0gc3VtbWFyeShGU0cyKSRyLnNxCnN1bW1hcnkoRlNHMikkci5zcSAtIHN1bW1hcnkoRlNHMykkci5zcQpzdW1tYXJ5KEZTRzMpJHIuc3EKYGBgCgpgYGB7cn0KYmRzICU+JSBmaWx0ZXIocHJvamVjdCA9PSAiRVROUCIpICU+JSBzZWxlY3QocHJvZmlsZSwgZGVwdGgsIEZsdXhfU21vb3RoKSAlPiUgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHByb2ZpbGUsIHZhbHVlc19mcm9tID0gRmx1eF9TbW9vdGgpCmBgYAoKU29tZXRoaW5nIGlzIG9mZi4gQWxsIG9mIHRoZSBmbHV4IHByb2ZpbGVzIGFyZSBpZGVudGljYWwuClNraXAgdGhpcwpgYGB7cn0KY2IxMCA8LSBjKCcjYTZjZWUzJywnIzFmNzhiNCcsJyNiMmRmOGEnLCcjMzNhMDJjJywnI2ZiOWE5OScsJyNlMzFhMWMnLCcjZmRiZjZmJywnI2ZmN2YwMCcsJyNjYWIyZDYnLCcjNmEzZDlhJykKcGx0MSA8LSBiZHMgJT4lICNmaWx0ZXIoREZQID4gMSkgJT4lICNmaWx0ZXIocHJvZmlsZSAlaW4lIGMoInN0bl8wNDMiLCAicDE2bl8xMDAiKSkgJT4lCiAgZ2dwbG90KGFlcyh5ID0gZGVwdGgsIHggPSBERlAsIGNvbCA9IGZhY3Rvcih0aW1lKSwgc2hhcGUgPSBmYWN0b3IodGltZSkpKSArIGZhY2V0X3dyYXAofnByb2plY3QpICsgZ2VvbV9wb2ludCgpICsgc2NhbGVfeV9yZXZlcnNlKGxpbWl0cyA9IGMoMTAwMCwgMCkpICsgeGxpbShjKDAuNSwgMS41KSkrIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDEpICsKICAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMocmVwKCJibGFjayIsIDUpLCByZXAoImJsdWUiLCA1KSkpICsgc2NhbGVfc2hhcGVfbWFudWFsKHZhbHVlcyA9IHJlcCgxOjUsIDIpKQoKcGxvdGx5OjpnZ3Bsb3RseShwbHQxKQpgYGAKCldoYXQgdGhlIGhlY2sgaXMgZ29pbmcgb24gd2l0aCBERlAgaGVyZS4gV2h5IGlzIGl0IHVzdWFsbHkgPiAxIHNob3VsZG4ndCBpdCBiZSBsZXNzIHRoYW4gMSB3aGVuIGZsdXggaXMgZGVjcmVhc2luZz8KVGhpcyB2ZXJ5IGRlZXAgaW5jcmVhc2luZyBmbHV4IHNlZW1zIGltcHJvYmFibGUgdG8gbWUuCkxldHMgY2hlY2sgdGhlIHNtb290aHMuIE9yIG9ubHkgZ28gdG8gMTAwMG0uCgosIGxlZ2VuZC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLCBsZWdlbmQuYm94LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoKQpgYGB7ciBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD00fQpzY2llbnRpZmljXzEwIDwtIGZ1bmN0aW9uKHgpIHtwYXJzZSh0ZXh0PWdzdWIoImVcXCsqIiwgIiAlKiUgMTBeIiwgc2NhbGVzOjpzY2llbnRpZmljX2Zvcm1hdCgpKHgpKSkgfQpzY2llbnRpZmljXzEwX2IgPC0gZnVuY3Rpb24oeCkge3BhcnNlKHRleHQ9Z3N1YigiZVxcKyoiLCAiICUqJSAxMF4iLCBzY2FsZXM6OnNjaWVudGlmaWNfZm9ybWF0KCkoeCkpKSB9CgpzY2llbnRpZmljXzEwX2MgPC0gZnVuY3Rpb24oeCkgewogICAgeG91dCA8LSBnc3ViKCIxZSIsICIxMF57IiwgZm9ybWF0KHgpLGZpeGVkPVRSVUUpCiAgICB4b3V0IDwtIGdzdWIoInstMCIsICJ7LSIsIHhvdXQsZml4ZWQ9VFJVRSkKICAgIHhvdXQgPC0gZ3N1YigieysiLCAieyIsIHhvdXQsZml4ZWQ9VFJVRSkKICAgIHhvdXQgPC0gZ3N1YigiezAiLCAieyIsIHhvdXQsZml4ZWQ9VFJVRSkKICAgIHhvdXQgPC0gcGFzdGUoeG91dCwifSIsc2VwPSIiKQogICAgcmV0dXJuKHBhcnNlKHRleHQ9eG91dCkpCiAgICAKfQoKc2NhbGVfeF9sb2cxMG5pY2UgPC0gZnVuY3Rpb24obmFtZT1OVUxMLG9tYWc9c2VxKC0xMCwyMCksLi4uKSB7CiAgICBicmVha3MxMCA8LSAxMF5vbWFnCiAgICBzY2FsZV94X2xvZzEwKGJyZWFrcz1icmVha3MxMCxsYWJlbHM9c2NpZW50aWZpY18xMF9jKGJyZWFrczEwKSwuLi4pCn0KCgojaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMTA3NjIyODcvaG93LWNhbi1pLWZvcm1hdC1heGlzLWxhYmVscy13aXRoLWV4cG9uZW50cy13aXRoLWdncGxvdDItYW5kLXNjYWxlcwojamFjb2JfbWFnbml0dWRlIDwtIGZ1bmN0aW9uKHgpe2V4cHJlc3Npb24oMTBecm91bmQobG9nMTAoeCkpKX0KCmNiMTAgPC0gYygnI2E2Y2VlMycsJyMxZjc4YjQnLCcjYjJkZjhhJywnIzMzYTAyYycsJyNmYjlhOTknLCcjZTMxYTFjJywnI2ZkYmY2ZicsJyNmZjdmMDAnLCcjY2FiMmQ2JywnIzZhM2Q5YScpCnBsdEZseCA8LSBiZHMgJT4lIGZpbHRlcihwcm9qZWN0ID09ICJFVE5QIikgJT4lICNmaWx0ZXIoREZQID4gMSkgJT4lICNmaWx0ZXIocHJvZmlsZSAlaW4lIGMoInN0bl8wNDMiLCAicDE2bl8xMDAiKSkgJT4lCiAgZ2dwbG90KGFlcyh5ID0gZGVwdGgsIHggPSBGbHV4X1Ntb290aCwgc2hhcGUgPSBmYWN0b3IoZGF5KHRpbWUpKSwgZmlsbCA9IGhvdXIodGltZSksIGdyb3VwID0gZmFjdG9yKHRpbWUpKSkgICsgZ2VvbV9wb2ludChzaXplID0gMiwgc3Ryb2tlID0gMSkrCiAgI2dlb21fcGF0aCgpICsKICBzY2FsZV95X3JldmVyc2UobGltaXRzID0gYygxMDAwLCAwKSkrCiAgc2NhbGVfeF9sb2cxMG5pY2UoKSsKICAjc2NhbGVfeF9sb2cxMCgpICsgCiAgIHNjYWxlX2NvbG9yX2dyYWRpZW50Mihsb3cgPSAiZGFya2dyZWVuIiwgbWlkID0gImdyYXk4MCIsIGhpZ2ggPSAicHVycGxlIiwgbWlkcG9pbnQgPSAxMCkgKyBzY2FsZV9zaGFwZV9tYW51YWwobmFtZSA9ICJEYXkgb2YgTW9udGgiLCB2YWx1ZXMgPSByZXAoMjE6MjUsIDIpKSArIAogIHNjYWxlX2ZpbGxfZ3JhZGllbnRuKG5hbWUgPSAiSG91ciBvZiBEYXkiLCBicmVha3MgPSBjKDAsIDYsIDEyLCAxOCwgMjQpLCBjb2xvcnMgPSBjKCJibGFjayIsICJibHVlIiwgIndoaXRlIiwgIm9yYW5nZSIsICJibGFjayIpKSArCiAgCiAgbGFicyh4ID0gYnF1b3RlKFNtb290aGVkfkZsdXh+KMK1bW9sfkMvbV4yL2QpKSwgeSA9ICJEZXB0aCAobSkiKSArCiAgI2xhYnMoeCA9ICJtb28iLCB5ID0gIkRlcHRoIChtKSIpICsKICBnZW9tX3JlY3QoZGF0YSA9IGRhdGEuZnJhbWUocHJvamVjdCA9ICJFVE5QIiksIGFlcyh4bWluID0gMjAsIHhtYXggPSAxODAsIHltaW4gPSA3NSwgeW1heCA9IDUwMCksIGNvbG91ciA9ICJyZWQiLCBmaWxsID0gTkEsIGluaGVyaXQuYWVzID0gRkFMU0UpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCB2anVzdCA9IC4zKSwgbGVnZW5kLnNwYWNpbmcgPSB1bml0KC4xLCAiY20iKSkgKwogICBnZW9tX3NlZ21lbnQoYWVzKHkgPSAxNjAsIHllbmQgPSAxNjAsIHggPSAyMCwgeGVuZCA9IDUwMCksIGNvbG9yID0gImRhcmtncmVlbiIsIHN0cm9rZSA9IDAuNSkrCiAgIGdlb21fc2VnbWVudChhZXMoeSA9IDg1MCwgeWVuZCA9IDg1MCwgeCA9IDIwLCB4ZW5kID0gNTAwKSwgY29sb3IgPSAiZGFya2JsdWUiLCBzdHJva2UgPSAwLjUpIysgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gODUwLCBjb2xvciA9ICJkYXJrYmx1ZSIpCgoKCnBsdEZseE5vTGVnZW5kIDwtIHBsdEZseCArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikKcGx0Rmx4TGVnZW5kIDwtIGdldF9sZWdlbmQocGx0Rmx4KQoKcGx0Rmx4CiNwbG90bHk6OmdncGxvdGx5KHBsdDEpCmBgYAoKYGBge3IgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9NH0KY2IxMCA8LSBjKCcjYTZjZWUzJywnIzFmNzhiNCcsJyNiMmRmOGEnLCcjMzNhMDJjJywnI2ZiOWE5OScsJyNlMzFhMWMnLCcjZmRiZjZmJywnI2ZmN2YwMCcsJyNjYWIyZDYnLCcjNmEzZDlhJykKcGx0Rmx4Wm9vbSA8LSBiZHMgJT4lIGZpbHRlcihwcm9qZWN0ID09ICJFVE5QIiAmIGRlcHRoIDw9IDUwMCAmIGRlcHRoID49IDc1KSAlPiUgI2ZpbHRlcihwcm9maWxlICVpbiUgYygic3RuXzA0MyIsICJwMTZuXzEwMCIpKSAlPiUKICBnZ3Bsb3QoYWVzKHkgPSBkZXB0aCwgeCA9IEZsdXhfU21vb3RoLCBzaGFwZSA9IGZhY3RvcihkYXkodGltZSkpLCBmaWxsID0gaG91cih0aW1lKSwgZ3JvdXAgPSBmYWN0b3IodGltZSkpKSArIGdlb21fcG9pbnQoc2l6ZSA9IDIsIHN0cm9rZSA9IDEpKwogICNnZW9tX3BhdGgoKSArCiAgc2NhbGVfeV9yZXZlcnNlKCkrCiAgI3NjYWxlX3hfbG9nMTAoKSArCiAgc2NhbGVfeF9sb2cxMChicmVha3MgPSBjKHNlcShmcm9tID0gMjAsIHRvID0gNTAsIGJ5ID0gMTApLCBzZXEoZnJvbSA9IDYwLCB0byA9IDE4MCwgYnkgPSAyMCkpLCBsaW1pdHMgPSBjKDIwLCAxODApKSArCiAgIHNjYWxlX2NvbG9yX2dyYWRpZW50Mihsb3cgPSAiZGFya2dyZWVuIiwgbWlkID0gImdyYXk4MCIsIGhpZ2ggPSAicHVycGxlIiwgbWlkcG9pbnQgPSAxMCkgKyBzY2FsZV9zaGFwZV9tYW51YWwodmFsdWVzID0gcmVwKDIxOjI1LCAyKSkgKyAKICBzY2FsZV9maWxsX2dyYWRpZW50bihicmVha3MgPSBjKDAsIDYsIDEyLCAxOCwgMjQpLCBjb2xvcnMgPSBjKCJibGFjayIsICJibHVlIiwgIndoaXRlIiwgIm9yYW5nZSIsICJibGFjayIpKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpICsKbGFicyh4ID0gIlNtb290aGVkIEZsdXgiLCB5ID0gIkRlcHRoIikgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpKwpnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAxNjAsIGNvbG9yID0gImRhcmtncmVlbiIpCgpwbHRGbHhab29tCiNwbG90bHk6OmdncGxvdGx5KHBsdDEpCmBgYAoKCgpgYGB7ciBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD00fQpjYjEwIDwtIGMoJyNhNmNlZTMnLCcjMWY3OGI0JywnI2IyZGY4YScsJyMzM2EwMmMnLCcjZmI5YTk5JywnI2UzMWExYycsJyNmZGJmNmYnLCcjZmY3ZjAwJywnI2NhYjJkNicsJyM2YTNkOWEnKQpwbHREZWx0YTMgPC0gYmRzICU+JSBmaWx0ZXIocHJvamVjdCA9PSAiRVROUCIpICU+JSAjZmlsdGVyKERGUCA+IDEpICU+JSAjZmlsdGVyKHByb2ZpbGUgJWluJSBjKCJzdG5fMDQzIiwgInAxNm5fMTAwIikpICU+JQogIGdncGxvdChhZXMoeSA9IGRlcHRoLCB4ID0gcHJhY21hOjpudGhyb290KERGL0RaLCA1KSwgc2hhcGUgPSBmYWN0b3IoZGF5KHRpbWUpKSwgZmlsbCA9IGhvdXIodGltZSksIGdyb3VwID0gZmFjdG9yKHRpbWUpKSkgICsgZ2VvbV9wb2ludChzaXplID0gMiwgc3Ryb2tlID0gMSkrCiAgI2dlb21fcGF0aCgpICsKICBzY2FsZV95X3JldmVyc2UobGltaXRzID0gYygxMDAwLCAwKSkrCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoLTIuMSwgLjYpLCBicmVha3MgPSBzZXEoZnJvbSA9IC0yLCB0byA9IC43NSwgYnkgPSAwLjUpKSArCiAgI3NjYWxlX3hfbG9nMTAoKSArCiAgIHNjYWxlX2NvbG9yX2dyYWRpZW50Mihsb3cgPSAiZGFya2dyZWVuIiwgbWlkID0gImdyYXk4MCIsIGhpZ2ggPSAicHVycGxlIiwgbWlkcG9pbnQgPSAxMCkgKyBzY2FsZV9zaGFwZV9tYW51YWwobmFtZSA9ICJEYXkgb2YgTW9udGgiLCB2YWx1ZXMgPSByZXAoMjE6MjUsIDIpKSArIAogIHNjYWxlX2ZpbGxfZ3JhZGllbnRuKG5hbWUgPSAiSG91ciIsIGJyZWFrcyA9IGMoMCwgNiwgMTIsIDE4LCAyNCksIGNvbG9ycyA9IGMoImJsYWNrIiwgImJsdWUiLCAid2hpdGUiLCAib3JhbmdlIiwgImJsYWNrIikpICsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwKSArCiAgbGFicyh4ID0gYnF1b3RlKChERi9EWileezEvNX1+KMK1bW9sQy9tXjMvZCleezEvNX0pLCB5ID0gIkRlcHRoIChtKSIpICsgdGhlbWUobGVnZW5kLnBvcyA9ICJub25lIikrCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMTYwLCBjb2xvciA9ICJkYXJrZ3JlZW4iKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDg1MCwgY29sb3IgPSAiZGFya2JsdWUiKQogICNsYWJzKHggPSAiKERGL0RaKSBeIDEvNSAowrVtb2wgQy9tXjMvZCkgXiAxLzUiKQoKcGx0RGVsdGEzCiNwbG90bHk6OmdncGxvdGx5KHBsdDFwb3MpCmBgYAoKCmBgYHtyIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoID0gOH0KIyAjcGxvdF9ncmlkKHBsdEZseE5vTGVnZW5kLCBwbHRGbHhab29tLCBwbHREZWx0YTMsIHBsdEZseExlZ2VuZCkKIyAKIyBwbHRGbHhMZWdlbmQgPC0gZ2V0X2xlZ2VuZChwbHRGbHggKyB0aGVtZShsZWdlbmQuYm94Lm1hcmdpbiA9IG1hcmdpbigwLCAwLCA0MCwgMTApKSkKIyAKIyBwZ1RvcCA8LSBwbG90X2dyaWQocGx0Rmx4Tm9MZWdlbmQsIHBsdEZseFpvb20gKyB0aGVtZShwbG90Lm1hcmdpbiA9IHVuaXQoYygxLCAwLCAzLCAwKSwgdW5pdHMgPSAiY20iKSksIHJlbF93aWR0aHMgPSBjKDIsIDEpLCBsYWJlbHMgPSBjKCJBIiwgIkIiKSkKIyBwZ0JvdHRvbSA8LSBwbG90X2dyaWQocGx0RGVsdGEzLCBwbHRGbHhMZWdlbmQgLCByZWxfd2lkdGhzID0gYygzLCAxKSwgbGFiZWxzID0gYygiQyIsICIiKSwgbGFiZWxfc2l6ZSA9IDE0KQojIHBnQm90aCA8LSBwbG90X2dyaWQocGdUb3AsIHBnQm90dG9tLCBuY29sID0gMSkKIyAKIyBwZ0JvdGgKIyAKIyBnZ3NhdmUoImZpZ3VyZXMvRmx1eERlZXBEaXZlLnBuZyIpCiMgZ2dzYXZlKCJmaWd1cmVzL0ZsdXhEZWVwRGl2ZS5zdmciKQoKYGBgCgoKV2l0aGluIHBhbmVsIGRyYXdpbmcKCgpgYGB7ciBmaWcuaGVpZ2h0ID0gNSwgZmlnLndpZHRoID0gNX0KcGdUb3AgPC0gZ2dkcmF3KHBsdEZseE5vTGVnZW5kIAogICAgICAgKSArCiAgZHJhd19wbG90KHBsdEZseFpvb20sIC40LCAuMjUsIC41NSwgLjYwKSArCiAgZHJhd19wbG90X2xhYmVsKAogICAgYygiIiwiQiIpLAogICAgYyguMDUsIDAuNTUpLAogICAgYygxLCAwLjg1KSwKICAgIHNpemUgPSAxNgogICkKcGdUb3AKYGBgCnBnQm90dG9tIDwtIHBsb3RfZ3JpZChwbHREZWx0YTMsIHBsdEZseExlZ2VuZCAsIHJlbF93aWR0aHMgPSBjKDMsIDEpLCBsYWJlbHMgPSBjKCJDIiwgIiIpLCBsYWJlbF9zaXplID0gMTQpCgoKCgpJIGRvbid0IGtub3cgd2hhdHMgZ29pbmcgb24gYmVsb3cgaGVyZQoKYGBge3IgZmlnLmhlaWdodCA9IDksIGZpZy53aWR0aCA9IDV9CnBnQm90dG9tIDwtIHBsdERlbHRhMyAgKyBnZW9tX3JlY3QoYWVzKHhtaW4gPSAtMiwgeG1heCA9IC0xLjE1LCB5bWluID0gMTcwLCB5bWF4ID0gMTAwMCksIGNvbG91ciA9ICJncmF5NTAiLCBmaWxsID0gTkEsIGluaGVyaXQuYWVzID0gRkFMU0UpICsgZHJhd19wbG90KHBsdEZseExlZ2VuZCAsIC0xLjksIC01NzUsIC43KQpwZ0JvdGggPC0gcGxvdF9ncmlkKHBnVG9wICsgdGhlbWUocGxvdC5tYXJnaW4gPSB1bml0KGMoMCwgMCwgMCwgMCksIHVuaXRzID0gImNtIikpLAogICAgICAgICAgICAgICAgICAgIHBnQm90dG9tICsgdGhlbWUocGxvdC5tYXJnaW4gPSB1bml0KGMoMCwgMCwgMCwgMCksIHVuaXRzID0gImNtIikpLAogICAgICAgICAgICAgICAgICAgIG5jb2wgPSAxLCByZWxfaGVpZ2h0cyA9IGMoNCwgNCksIGxhYmVscyA9IGMoIkEiLCAiQyIpLCBsYWJlbF9zaXplID0gMTYpCnBnQm90aAoKZ2dzYXZlKCJmaWd1cmVzL0ZsdXhEZWVwRGl2ZS5wbmciKQpnZ3NhdmUoImZpZ3VyZXMvRmx1eERlZXBEaXZlLnN2ZyIpCmBgYAoKCgpgYGB7ciBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aCA9IDh9CiMgI3Bsb3RfZ3JpZChwbHRGbHhOb0xlZ2VuZCwgcGx0Rmx4Wm9vbSwgcGx0RGVsdGEzLCBwbHRGbHhMZWdlbmQpCiMgCiMgcGx0Rmx4TGVnZW5kIDwtIGdldF9sZWdlbmQocGx0Rmx4ICsgdGhlbWUobGVnZW5kLmJveC5tYXJnaW4gPSBtYXJnaW4oMCwgMCwgNDAsIDEwKSkpCiMgCiMgcGdUb3AgPC0gcGxvdF9ncmlkKHBsdEZseE5vTGVnZW5kICsgeWxpbShjKDEwMDAsIDApKSwgcGx0Rmx4Wm9vbSArIHRoZW1lKHBsb3QubWFyZ2luID0gdW5pdChjKDEsIDAsIDMsIDApLCB1bml0cyA9ICJjbSIpKSwgcmVsX3dpZHRocyA9IGMoMiwgMSksIGxhYmVscyA9IGMoIkEiLCAiQiIpKQojIHBnQm90dG9tIDwtIHBsb3RfZ3JpZChwbHREZWx0YTMgKyB5bGltKGMoMTAwMCwgMCkpLCBwbHRGbHhMZWdlbmQgLCByZWxfd2lkdGhzID0gYygzLCAxKSwgbGFiZWxzID0gYygiQyIsICIiKSkKIyBwZ0JvdGggPC0gcGxvdF9ncmlkKHBnVG9wLCBwZ0JvdHRvbSwgbmNvbCA9IDEpCiMgCiMgcGdCb3RoCiMgCiMgI2dnc2F2ZSgiZmlndXJlcy9GbHV4U2hhbGxvd0RpdmUucG5nIikKIyAjZ2dzYXZlKCJmaWd1cmVzL0ZsdXhTaGFsbG93RGl2ZS5zdmciKQoKYGBgCgpUZXN0IGZvciBkYXkgdG8gZGF5IGFuZCBob3VybHkgdmFyaWFiaWxpdHkgaW4gZGVsdGEgZmx1eApgYGB7cn0KYmRzQWRkVGltZSA8LSBiZHMgJT4lIAogIG11dGF0ZShIb3VyID0gaG91cih0aW1lKSwgRGF5ID0gZGF5KHRpbWUpKQoKREZHMSA8LSBnYW0ocHJhY21hOjpudGhyb290KERGL0RaLCA1KX4gcyhkZXB0aCwgayA9IDMpICsgcyhEYXksIGsgPSAzKSArIHMoSG91ciwgayA9IDQsIGJzID0gImNjIiksIGtub3RzID0gbGlzdChIb3VyID0gYygwLCAyNCkpLCBkYXRhID0gYmRzQWRkVGltZSAlPiUgZmlsdGVyKGRlcHRoID49IDI1MCAmIGRlcHRoIDw9NTAwICYgcHJvamVjdCA9PSAiRVROUCIpKQoKREZHMiA8LSBnYW0ocHJhY21hOjpudGhyb290KERGL0RaLCA1KSB+IHMoZGVwdGgsIGsgPSAzKSArIHMoRGF5LCBrID0gMyksIGRhdGEgPSBiZHNBZGRUaW1lICU+JSBmaWx0ZXIoZGVwdGggPj0gMjUwICYgZGVwdGggPD01MDAgJiBwcm9qZWN0ID09ICJFVE5QIikpCgpERkczIDwtIGdhbShwcmFjbWE6Om50aHJvb3QoREYvRFosIDUpIH4gcyhkZXB0aCwgayA9IDMpLCBkYXRhID0gYmRzQWRkVGltZSAlPiUgZmlsdGVyKGRlcHRoID49IDI1MCAmIGRlcHRoIDw9NTAwICYgcHJvamVjdCA9PSAiRVROUCIpKQoKc3VtbWFyeShERkcxKQpzdW1tYXJ5KERGRzIpCnN1bW1hcnkoREZHMykKCnN1bW1hcnkoREZHMSkkci5zcSAtIHN1bW1hcnkoREZHMikkci5zcQpzdW1tYXJ5KERGRzIpJHIuc3EgLSBzdW1tYXJ5KERGRzMpJHIuc3EKc3VtbWFyeShERkczKSRyLnNxCmBgYApwbmcoZmlsZW5hbWUgPSAiLi9maWd1cmVzL0NvbWJpbmVkUDJJbmZvLnBuZyIsIHdpZHRoID0gMTAsIGhlaWdodCA9IDgsIHVuaXRzID0gImluIiwgcmVzID0gMjAwKQpTdGF0aW9uSW5mb1Bsb3QoKQpkZXYub2ZmKCkKYGBge3IgZmlnLmhlaWdodCA9IDgsIGZpZy53aWR0aCA9IDEwfQojcGxvdC5uZXcoKQpGbHV4R2FtUGxvdCA8LSBmdW5jdGlvbigpewogIHBhcihtZnJvdyA9IGMoMiwyKSkKICBwbG90KERGRzEpCiAgbXRleHQoZXhwcmVzc2lvbihib2xkKCJDIikpLCBzaWRlID0gMywgbGluZSA9IDAsIGFkaiA9IDAsIGNleCA9IDIpCiAgcGFyKG1mZyA9IGMoMSwxKSkKICBtdGV4dChleHByZXNzaW9uKGJvbGQoIkEiKSksIHNpZGUgPSAzLCBsaW5lID0gMCwgYWRqID0gMCwgY2V4ID0gMikKICBwYXIobWZnID0gYygxLDIpKQogIG10ZXh0KGV4cHJlc3Npb24oYm9sZCgiQiIpKSwgc2lkZSA9IDMsIGxpbmUgPSAwLCBhZGogPSAwLCBjZXggPSAyKQp9CgpGbHV4R2FtUGxvdCgpCgpwbmcoZmlsZW5hbWUgPSAiLi9maWd1cmVzL0ZsdXhHYW1QbG90LnBuZyIsIHdpZHRoID0gMTAsIGhlaWdodCA9IDgsIHVuaXRzID0gImluIiwgcmVzID0gMjAwKQpGbHV4R2FtUGxvdCgpCmRldi5vZmYoKQpgYGAKCkNoZWNrIG9mIGFjdHVhbCBkYXRhIGZvciBob3VyCmBgYHtyfQpnZ3Bsb3QoZGF0YSA9IGJkcyAlPiUgZmlsdGVyKGRlcHRoID49IDE3NSwgZGVwdGggPD0gNTAwKSwgYWVzKHkgPSBERi9EWiwgeCA9IGhvdXIodGltZSksIGNvbCA9IGRlcHRoLCBncm91cCA9IGRlcHRoKSkgKyBnZW9tX3BvaW50KCkgKyBnZW9tX2xpbmUoKQpgYGAKCgojT3NwcwoKKHUgbW9sIEMgLyBtXjMgLyBkYXkpCmBgYHtyIGZpZy53aWR0aCA9IDYsIGZpZy5oZWlnaHQgPSA0fQpkaXNhZ0ZpZyA8LSBiZHMgJT4lIGZpbHRlcihwcm9qZWN0ID09ICJFVE5QIikgJT4lCiAgZ2dwbG90KGFlcyh5ID0gZGVwdGgsIHggPSBwcmFjbWE6Om50aHJvb3Qob3Nwc0RaLCAzKSwgc2hhcGUgPSBmYWN0b3IoZGF5KHRpbWUpKSwgZmlsbCA9IGhvdXIodGltZSksIGdyb3VwID0gZmFjdG9yKHRpbWUpKSkgKyBnZW9tX3BvaW50KHNpemUgPSAyKSArIHNjYWxlX3lfcmV2ZXJzZShsaW1pdHMgPSBjKDEwMDAsIDApKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoLTEsIDEpKSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCkgKyAgIHNjYWxlX3NoYXBlX21hbnVhbChuYW1lID0gIkRheSBvZiBNb250aCIsIHZhbHVlcyA9IHJlcCgyMToyNSwgMikpICsKICAjbGFicyh4ID0gYnF1b3RlKCJPYnNlcnZlZCAtIE1vZGVsZWQgU21hbGwgUGFydGljbGUgRmx1eCJ+KM68bW9sL21eMy9kYXkpKSwgeSA9ICJEZXB0aCAobSkiKSArCiAgbGFicyh4ID0gcGFzdGUoIk9TTVMiLCBleHByZXNzaW9uKCjOvG1vbC9tXjMvZGF5KSkpKSArCiAgc2NhbGVfZmlsbF9ncmFkaWVudG4obmFtZSA9ICJIb3VyIG9mIERheSIsIGJyZWFrcyA9IGMoMCwgNiwgMTIsIDE4LCAyNCksIGNvbG9ycyA9IGMoImJsYWNrIiwgImJsdWUiLCAid2hpdGUiLCAib3JhbmdlIiwgImJsYWNrIikpICsgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMTc1LCBjb2xvciA9ICJkYXJrZ3JlZW4iKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDg1MCwgY29sb3IgPSAiZGFya2JsdWUiKQpkaXNhZ0ZpZwojZ2dzYXZlKCIuLmZpZ3VyZXMvRmx1eFNpemVTaGlmdC5zdmciCgogZ2dzYXZlKCJmaWd1cmVzL0ZsdXhTaXplU2hpZnQucG5nIikKIGdnc2F2ZSgiZmlndXJlcy9GbHV4U2l6ZVNoaWZ0LnN2ZyIpCmBgYAoKIyMjIENsYXJhIEZpZwpGb3IgTlNGIFByb3Bvc2FsCnBsb3RfZ3JpZCgKICBQbG90UGFydGljbGVzbWFueSwKICBQbG90UFNEbWFueSwKICByZWxfd2lkdGhzID0gYygyLCAzKQogICkKYGBge3IgZmlnLmhlaWdodCA9IDgsIGZpZy53aWR0aCA9IDEwfQoKcGdUb3AgPC0gZ2dkcmF3KHBsdEZseE5vTGVnZW5kIAogICAgICAgKSArCiAgZHJhd19wbG90KHBsdEZseFpvb20sIC40LCAuMjUsIC41NSwgLjYwKSArCiAgZHJhd19wbG90X2xhYmVsKAogICAgYygiIiwiRCIpLAogICAgYyguMDUsIDAuNTUpLAogICAgYygxLCAwLjg1KSwKICAgIHNpemUgPSAxNgogICkKCnBnQ0YgPC0gcGxvdF9ncmlkKFBsb3RQYXJ0aWNsZXNtYW55ICsgeWxpbShjKDEwMDAsIDApKSwKICAgICAgICAgICAgICAgICAgUGxvdFBTRG1hbnkgKyB5bGltKGMoMTAwMCwgMCkpICt0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpLAogICAgICAgICAgICAgICAgICBwZ1RvcCArIHRoZW1lKHBsb3QubWFyZ2luID0gdW5pdChjKDAsIDAsIDAsIDApLCB1bml0cyA9ICJjbSIpKSwKICAgICAgICAgICAgICAgICAgICBkaXNhZ0ZpZyArIHRoZW1lKHBsb3QubWFyZ2luID0gdW5pdChjKDAsIDAsIC4yLCAwKSwgdW5pdHMgPSAiY20iKSksCiAgICAgICAgICAgICAgICAgICAgbmNvbCA9IDIsIHJlbF9oZWlnaHRzID0gYyg0LCA0KSwgbGFiZWxzID0gYygiQSIsICJCIiwgIkMiLCAiRSIpLCBsYWJlbF9zaXplID0gMTYpCnBnQ0YKCmdnc2F2ZSgiLi9maWd1cmVzL1VWUF9mb3Jfem9vcF9wcm9wb3NhbC5wbmciLCBwZ0NGLCB3aWR0aCA9IDEwLCBoZWlnaHQgPSA4LCB1bml0cyA9ICJpbiIpCmBgYAoKYGBge3J9CmJkc0FkZFRpbWUgPC0gYmRzICU+JQogIG11dGF0ZShIb3VyID0gaG91cih0aW1lKSwgRGF5ID0gZGF5KHRpbWUpKQoKT1pHMSA8LSBnYW0ob3Nwc0RaIH4gcyhkZXB0aCwgayA9IDMpICsgcyhEYXksIGsgPSAzKSArIHMoSG91ciwgayA9IDQsIGJzID0gImNjIiksIGtub3RzID0gbGlzdChIb3VyID0gYygwLCAyNCkpLCBkYXRhID0gYmRzQWRkVGltZSAlPiUgZmlsdGVyKGRlcHRoID49IDE3NSAmIGRlcHRoIDw9NTAwICYgcHJvamVjdCA9PSAiRVROUCIpKQoKT1pHMiA8LSBnYW0ob3Nwc0RaIH4gcyhkZXB0aCwgayA9IDMpICsgcyhEYXksIGsgPSAzKSwgZGF0YSA9IGJkc0FkZFRpbWUgJT4lIGZpbHRlcihkZXB0aCA+PSAxNzUgJiBkZXB0aCA8PTUwMCAmIHByb2plY3QgPT0gIkVUTlAiKSkKCk9aRzMgPC0gZ2FtKG9zcHNEWiB+IHMoZGVwdGgsIGsgPSAzKSwgZGF0YSA9IGJkc0FkZFRpbWUgJT4lIGZpbHRlcihkZXB0aCA+PSAxNzUgJiBkZXB0aCA8PTUwMCAmIHByb2plY3QgPT0gIkVUTlAiKSkKCnN1bW1hcnkoT1pHMSkKc3VtbWFyeShPWkcyKQpzdW1tYXJ5KE9aRzMpCgpzdW1tYXJ5KE9aRzEpJHIuc3EgLSBzdW1tYXJ5KE9aRzIpJHIuc3EKc3VtbWFyeShPWkcyKSRyLnNxIC0gc3VtbWFyeShPWkczKSRyLnNxCnN1bW1hcnkoT1pHMykkci5zcQpgYGAKCmBgYHtyfQpPU01TR2FtUGxvdCA8LSBmdW5jdGlvbigpewogIHBhcihtZnJvdyA9IGMoMSwyKSkKICBwbG90KE9aRzIpCiAgbXRleHQoZXhwcmVzc2lvbihib2xkKCJCIikpLCBzaWRlID0gMywgbGluZSA9IDAsIGFkaiA9IDAsIGNleCA9IDIpCiAgcGFyKG1mZyA9IGMoMSwxKSkKICBtdGV4dChleHByZXNzaW9uKGJvbGQoIkEiKSksIHNpZGUgPSAzLCBsaW5lID0gMCwgYWRqID0gMCwgY2V4ID0gMikKfQoKT1NNU0dhbVBsb3QoKQoKcG5nKGZpbGVuYW1lID0gIi4vZmlndXJlcy9PU01TR2FtUGxvdC5wbmciLCB3aWR0aCA9IDEwLCBoZWlnaHQgPSA2LCB1bml0cyA9ICJpbiIsIHJlcyA9IDIwMCkKT1NNU0dhbVBsb3QoKQoKZGV2Lm9mZigpCmBgYAoKYGBge3J9CnBsb3QoT1pHMikKYGBgCgoKYGBge3J9CmJkcyAlPiUgZmlsdGVyKHByb2plY3QgPT0gIlAxNiIpICU+JQogIGdncGxvdChhZXMoeSA9IGRlcHRoLCB4ID0gb3Nwc0RaKSkgKyBmYWNldF93cmFwKH5wcm9qZWN0KSArIGdlb21fcG9pbnQoKSArIHNjYWxlX3lfcmV2ZXJzZShsaW1pdHMgPSBjKDUwMCwgMCkpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCkKYGBgCgojIFRyYXAgZGF0YQpgYGB7cn0KdHJhcEZsdXgzIDwtIHJlYWRfY3N2KCJkYXRhT3V0L2ZsdXhNU19kaXN0aWxsZWQuY3N2IikKVVZQRmx1eENvbWIgPC0gcmVhZF9jc3YoImRhdGFPdXQvQ29tYmluZWRQcm9maWxlRmx1eEVzdF9EUy5jc3YiKQpVVlBGbHV4T0UgPC0gcmVhZF9jc3YoImRhdGFPdXQvT2JzZXJ2ZWRWc0V4cGVjdGVkRmx1eC5jc3YiKQoKYGBgCgpgYGB7cn0KdHJhcEZsdXgzCmBgYApgYGB7cn0KVVZQRmx1eENvbWIKYGBgCgoKYGBge3J9CgpmbHV4TVNfZGlzdGlsbGVkX3RvUGxvdCA8LSB0cmFwRmx1eDMgJT4lCiAgbXV0YXRlKFNhbXBsZVR5cGUgPSByZWNvZGUoU2FtcGxlVHlwZSwgYHBsdXMucGAgPSAicGx1cy1wYXJ0aWNsZXMiLCB0b3AgPSAidG9wLWNvbGxlY3RvciIpKQpgYGAKClJlbW92ZSB0cmFwcyB3aGVyZSBtYXNzIHNwZWMgZGlkbid0IHdvcmsgY29ycmVjdGx5CjItMTcgMTUwCjEtMTIgNzNtCjEtMTIgMTQ4CjItMTQgMTAwCnwoVHJhcElEID09ICIyLTE3IiAmIERlcHRoID09IDE1MCkKYGBge3J9CmZsdXhNU19kaXN0aWxsZWRfdG9QbG90MiA8LSBmbHV4TVNfZGlzdGlsbGVkX3RvUGxvdCAlPiUKIGZpbHRlcighKChUcmFwSUQgPT0gIjEtMTIiKSB8IChUcmFwSUQgPT0gIjItMTQiICYgRGVwdGggPT0gMTAwKXwoVHJhcElEID09ICIyLTE3IiAmIERlcHRoID09IDE1MCkpKQpmbHV4TVNfZGlzdGlsbGVkX3RvUGxvdDIKYGBgCgpgYGB7cn0KIyBVVlBGbHV4Q29tYiAlPiUKIyAgIGdncGxvdChhZXMoeSA9IGRlcHRoKSkgICsgc2NhbGVfeV9yZXZlcnNlKGxpbWl0cyA9IGMoMTAwMCwgMCkpICsKIyAgIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKDAsIDIwMCkpICsKIyAgIGdlb21fcG9pbnQoYWVzKHkgPSBEZXB0aCwgeCA9IENfZmx1eF91bW9sLCBmaWxsID0gU2FtcGxlVHlwZSwgc2hhcGUgPSBUcmFwVHlwZSksCiMgICAgICAgICAgICAgIGNvbG91ciA9ICJibGFjayIsIHN0cm9rZSA9IDEsIHNpemUgPSA1LCBkYXRhID0gZmx1eE1TX2Rpc3RpbGxlZF90b1Bsb3QpICsKIyAgIGdlb21fcG9pbnQoYWVzKHggPSBGbHV4KSwgc2l6ZSA9IDMsIHNoYXBlID0gMjEsIGNvbG9yID0gIndoaXRlIiwgZmlsbCA9ICJibGFjayIpICsKIyAgIGdlb21fcG9pbnQoYWVzKHggPSAtMSwgeSA9IC0xLCBzaXplID0gIlVWUCIpKSArICMgZHVtbXkgcG9pbnQgZm9yIHRoZSBsZWdlbmQKIyBzY2FsZV9zaGFwZV9tYW51YWwodmFsdWVzID0gYygyNSwgMjIpKSsKIyAgIHNjYWxlX3NpemVfbWFudWFsKHZhbHVlcyA9IDEsIG5hbWUgPSAiIikgKwojICAgeWxhYigiRGVwdGggKG0pIikgKyB4bGFiKCJGbHV4IMK1bW9sQy9tXjIvZGF5IikgKwojICAgZ3VpZGVzKGZpbGwgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChzaGFwZSA9IDIxKSkpICsKIyAgIHNjYWxlX2ZpbGxfdmlyaWRpc19kKCkgKwojICAgdGhlbWVfY293cGxvdCgpICsgCiMgICB0aGVtZSgKIyAgICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9IGMoMC41LCAwLjQpLAojICAgICAgICAgbGVnZW5kLmJveC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDAuNSksCiMgICAgICAgICBsZWdlbmQubWFyZ2luID0gbWFyZ2luKC0xMCwgNSwgMTAsIDUpCiMgICApICsKIyAgIGdlb21fcmVjdChkYXRhID0gZGF0YS5mcmFtZShwcm9qZWN0ID0gIkVUTlAiKSwgYWVzKHhtaW4gPSAxNSwgeG1heCA9IDMyLCB5bWluID0gNDUsIHltYXggPSAxOTUpLCBjb2xvdXIgPSAicmVkIiwgZmlsbCA9IE5BLCBpbmhlcml0LmFlcyA9IEZBTFNFKQojICBnZ3NhdmUoImZpZ3VyZXMvRml0dGVkRmx1eC5wbmciKQojICBnZ3NhdmUoImZpZ3VyZXMvRml0dGVkRmx1eC5zdmciKQpgYGAKClRyYXBzIHdoZXJlIG1hc3Mgc3BlYyBkaWRuJ3Qgd29yay4KCgpgYGB7cn0KVVZQRmx1eFBsb3QwMCA8LSBVVlBGbHV4Q29tYiAlPiUgCiAgZ2dwbG90KGFlcyh5ID0gZGVwdGgpKSAgKyBzY2FsZV95X3JldmVyc2UobGltaXRzID0gYygxMDAwLCAwKSkgKwogIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKDAsIDIwMCkpICsKICBnZW9tX3BvaW50KGFlcyh5ID0gRGVwdGgsIHggPSBDX2ZsdXhfdW1vbCwgc2hhcGUgPSBUcmFwVHlwZSwgSUQgPSBUcmFwSUQpLAogICAgICAgICAgICAgY29sb3VyID0gImJsYWNrIiwgc3Ryb2tlID0gMSwgc2l6ZSA9IDUsIGRhdGEgPSBmbHV4TVNfZGlzdGlsbGVkX3RvUGxvdDIpICsKICBnZW9tX2xpbmUoYWVzKHggPSBGbHV4KSwgc2l6ZSA9IDEsIGNvbG9yID0gImJsYWNrIikgKwogIGdlb21fcG9pbnQoYWVzKHggPSAtMSwgeSA9IC0xLCBzaXplID0gIlVWUCBFc3RpbWF0ZSIpKSArICMgZHVtbXkgcG9pbnQgZm9yIHRoZSBsZWdlbmQKICBnZW9tX3BvaW50KGFlcyh4ID0gdG90X2ZsdXgyKSwgc2l6ZSA9IDMsIHNoYXBlID0gMjEsIGNvbG9yID0gIndoaXRlIiwgZmlsbCA9ICJibGFjayIsIGRhdGEgPSBVVlBGbHV4T0UpICsKc2NhbGVfc2hhcGVfbWFudWFsKHZhbHVlcyA9IGMoMjUsIDIyKSkrCiAgc2NhbGVfc2l6ZV9tYW51YWwodmFsdWVzID0gMSwgbmFtZSA9ICIiKSArCiAgeWxhYigiRGVwdGggKG0pIikgKwogICN4bGFiKGV4cHJlc3Npb24oRmx1eCDCtW1vbEMvbV4yL2RheSkpICsKICB4bGFiKGV4cHJlc3Npb24ocGFzdGUoInggYXhpcyAiLCByaW5nKEEpXjIpKSkgKwogIHhsYWIoZXhwcmVzc2lvbihwYXN0ZSgiRmx1eCAowrVtb2xDLyIsIG1eMiwgIi9kYXkpIikpKSArCiAgCiAgZ3VpZGVzKGZpbGwgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChzaGFwZSA9IDIxKSkpICsKICB0aGVtZV9jb3dwbG90KCkgKyAKICB0aGVtZSgKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSBjKDAuNSwgMC40KSwKICAgICAgICBsZWdlbmQuYm94LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoY29sb3IgPSAiYmxhY2siLCBzaXplID0gMC41KSwKICAgICAgICBsZWdlbmQubWFyZ2luID0gbWFyZ2luKC0xMCwgNSwgMTAsIDUpCiAgKSAKIyBVVlBGbHV4UGxvdCA8LSBVVlBGbHV4UGxvdDAwICsKIyAgIGdlb21fcmVjdChkYXRhID0gZGF0YS5mcmFtZShwcm9qZWN0ID0gIkVUTlAiKSwgYWVzKHhtaW4gPSAxNSwgeG1heCA9IDMyLCB5bWluID0gNDUsIHltYXggPSAxOTUpLCBjb2xvdXIgPSAicmVkIiwgZmlsbCA9IE5BLCBpbmhlcml0LmFlcyA9IEZBTFNFKQoKVVZQRmx1eFBsb3QwMAoKZ2dzYXZlKCJmaWd1cmVzL0ZpdHRlZEZsdXgucG5nIikKZ2dzYXZlKCJmaWd1cmVzL0ZpdHRlZEZsdXguc3ZnIikKYGBgCgoKIyMgRXhhbXBsZSBwYXJ0aWNsZSBzaXplIGRpc3RyaWJ1dGlvbgoKaG9yaXpvbnRhbEdhbVBsb3QgPC0gZGF0YUdhbUhvcml6b250YWwgJT4lIGdncGxvdChhZXMoeCA9IHJlc3BfZml0LCB5ID0gZGVwdGgsIGNvbCA9IGxvZyhsYiksIGdyb3VwID0gbGIpKSArIHNjYWxlX3lfcmV2ZXJzZSgpICsgZ2VvbV9wb2ludCgpICsgc2NhbGVfeF9sb2cxMChsaW1pdHMgPSBjKDEwXi04LCBOQSkpICsgc2NhbGVfY29sb3JfdmlyaWRpc19jKCkgKyBnZW9tX3BhdGgoKSArIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDEpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gNSkgICsgZ2VvbV9lcnJvcmJhcihhZXMoeG1pbiA9IHJlc3BfbG93ZXIsIHhtYXggPSByZXNwX3VwcGVyKSwgd2lkdGggPSAxMCwgYWxwaGEgPSAwLjUpKyB0aGVtZV9idygpCgpgYGB7ciBmaWcud2lkdGg9IDEwfQpUUFBsb3QgPC0gYmVzICU+JSBmaWx0ZXIocHJvZmlsZSA9PSAic3RuXzA0MyIpICU+JSBncm91cF9ieShsYikgJT4lIGdncGxvdChhZXMoeCA9IFRvdGFsUGFydGljbGVzLCB5ID0gZGVwdGgsIGNvbCA9IGxvZyhsYiksIGdyb3VwID0gbGIpKSArIHNjYWxlX3lfcmV2ZXJzZShsaW1pdHMgPSBjKDEwMDAsIDApKSArIGdlb21fcG9pbnQoKSArIHNjYWxlX3hfbG9nMTAoKSArIHNjYWxlX2NvbG9yX3ZpcmlkaXNfYygpICsgZ2VvbV9wYXRoKCkgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAxKSArIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDUpICsgbGFicyh5ID0gIkRlcHRoIChtKSIsIHggPSAiVG90YWxQYXJ0aWNsZXMgT2JzZXJ2ZWQgKCMpIikKCm5ucFBsb3QgPC0gYmVzICU+JSBmaWx0ZXIocHJvZmlsZSA9PSAic3RuXzA0MyIpICU+JSBncm91cF9ieShsYikgJT4lIGdncGxvdChhZXMoeCA9IG5fbnBhcnRpY2xlcywgeSA9IGRlcHRoLCBjb2wgPSBsb2cobGIpLCBncm91cCA9IGxiKSkgKyBzY2FsZV95X3JldmVyc2UobGltaXRzID0gYygxMDAwLCAwKSkgKyBnZW9tX3BvaW50KCkgKyBzY2FsZV94X2xvZzEwKCkgKyBzY2FsZV9jb2xvcl92aXJpZGlzX2MoKSArIGdlb21fcGF0aCgpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMSkgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSA1KSArIGxhYnMoeSA9ICJEZXB0aCAobSkiLCB4ID0gIkJpbnNpemUgYW5kIFZvbHVtZSBOb3JtYWxpemVkIFBhcnRpY2xlcyAoIy9ML21tKSIpCgpGaXRQbG90IDwtIGJlcyAlPiUgZmlsdGVyKHByb2ZpbGUgPT0gInN0bl8wNDMiKSAlPiUgZ3JvdXBfYnkobGIpICU+JSBnZ3Bsb3QoYWVzKHggPSBubnBfc21vb3RoLCB4bWluID0gbm5wX2xvd2VyLCB4bWF4ID0gbm5wX3VwcGVyLCB5ID0gZGVwdGgsIGNvbCA9IGxvZyhsYiksIGdyb3VwID0gbGIpKSArIHNjYWxlX3lfcmV2ZXJzZShsaW1pdHMgPSBjKDEwMDAsIDApKSArIGdlb21fcG9pbnQoKSArIHNjYWxlX3hfbG9nMTAoKSArIHNjYWxlX2NvbG9yX3ZpcmlkaXNfYygpICsgZ2VvbV9wYXRoKCkgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAxKSArIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDUpICsgbGFicyh5ID0gIkRlcHRoIChtKSIsIHggPSAiU21vb3RoZWQgLSBOb3JtYWxpemVkIFBhcnRpY2xlcyAoIy9ML21tKSIpICsgZ2VvbV9lcnJvcmJhcih3aWR0aCA9IDEwLCBhbHBoYSA9IDAuNSkKCm5wTGVnZW5kIDwtIGdldF9sZWdlbmQoRml0UGxvdCArIHRoZW1lKGxlZ2VuZC5ib3gubWFyZ2luID0gbWFyZ2luKDAsIDAsIDQwLCAyMDApKSArIGxhYnMoY29sID0gZXhwcmVzc2lvbihsb2dbZV0oU2l6ZSAobW0pKSkpKQoKcGxvdF9ncmlkKAogIFRQUGxvdCArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiksCiAgbm5wUGxvdCArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiksCiAgbnBMZWdlbmQgLAogIEZpdFBsb3QgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpCikKCmdnc2F2ZSgiZmlndXJlcy9BbGxQYXJ0aWNsZVNpemVzLnN2ZyIpCmdnc2F2ZSgiZmlndXJlcy9BbGxQYXJ0aWNsZVNpemVzLnBuZyIpCmBgYAoKCiMjIFdlYmVyIEJpYW5jaGkgRmlncwoKCgoKYGBge3J9ClNhbWVHYW0gPC0gZ2FtKFRvdGFsUGFydGljbGVzIH5zKGxvZyhsYiksIGxvZyhkZXB0aCksIGJ5ID0gZmFjdG9yKHRpbWUpKSwgb2Zmc2V0ID0gbG9nKHZvbCAqIGJpbnNpemUpLCBmYW1pbHkgPSBuYigpLAogICAgZGF0YSA9IGJlcyAlPiUgZmlsdGVyKHByb2plY3QgPT0gIkVUTlAiKSkKYGBgCgpgYGB7cn0KYmVzRSA8LSBiZXMgJT4lIGZpbHRlcihwcm9qZWN0ID09ICJFVE5QIikKCmxiX25ldyA8LSBleHAoc2VxKGZyb20gPSBsb2coMC4xKSwgdG8gPSBsb2coMi4xKSwgYnkgPSAwLjA1KSkKdWJfbmV3IDwtIGxlYWQobGJfbmV3KQpiaW5zaXplX25ldyA8LSB1Yl9uZXcgLSBsYl9uZXcKCmxiYnMgPC0gdGliYmxlKGxiID0gbGJfbmV3LCB1YiA9IHViX25ldywgYmluc2l6ZSA9IGJpbnNpemVfbmV3KQoKRXhwYW5kZWQgPC0gZXhwYW5kX2dyaWQobGIgPSBleHAoc2VxKGZyb20gPSBsb2coMC4xKSwgdG8gPSBsb2coMiksIGJ5ID0gMC4wNSkpLCBkZXB0aCA9IHNlcShmcm9tID0gMjAsIHRvID0gMjAwMCwgYnkgPSAyMCksIHRpbWUgPSBhcy5mYWN0b3IodW5pcXVlKGJlc0UkdGltZSkpKSAlPiUgbGVmdF9qb2luKGxiYnMsIGJ5ID0gImxiIikKClByZWQgPC0gZXhwKHByZWRpY3QoU2FtZUdhbSwgRXhwYW5kZWQpKQpUb1Bsb3QgPC0gYmluZF9jb2xzKEV4cGFuZGVkLCBubnBhcnRpY2xlcyA9IFByZWQpICU+JSBtdXRhdGUodGltZSA9IGFzLmNoYXJhY3Rlcih0aW1lKSkgJT4lIG11dGF0ZShucGFydGljbGVzID0gbm5wYXJ0aWNsZXMgKiBiaW5zaXplKQpgYGAKCmBgYHtyfQpUb1Bsb3QgJT4lIGZpbHRlcihsYiA8PSAyKSAlPiUgIGdncGxvdChhZXMoeCA9IGxiLCB5ID0gZGVwdGgsIGZpbGwgPSBsb2cxMChubnBhcnRpY2xlcyksIHogPSBsb2cxMChubnBhcnRpY2xlcykpKSArIGdlb21fdGlsZSgpICsgc2NhbGVfZmlsbF92aXJpZGlzX2MoKSArIHNjYWxlX3lfcmV2ZXJzZSgpICsgc2NhbGVfeF9sb2cxMCgpICArIGZhY2V0X3dyYXAofnRpbWUpICsgZ2VvbV9jb250b3VyKGNvbG9yID0gImJsYWNrIikKYGBgCmBgYHtyfQptZWFuQmVzZSA8LSBUb1Bsb3QgJT4lIGZpbHRlcihsYiA8PSAyKSAlPiUgZ3JvdXBfYnkobGIsIGRlcHRoKSAlPiUgc3VtbWFyaXplKG5wYXJ0aWNsZXMgPSBtZWFuKG5wYXJ0aWNsZXMpLCBubnBhcnRpY2xlcyA9IG1lYW4obm5wYXJ0aWNsZXMpKQoKV0JDb2xvck1hcCA8LSBtZWFuQmVzZSU+JQogICBnZ3Bsb3QoYWVzKHggPSBsYiwgeSA9IGRlcHRoLCBmaWxsID0gbG9nMTAobm5wYXJ0aWNsZXMpLCB6ID0gbG9nMTAobm5wYXJ0aWNsZXMpKSkgKyBnZW9tX3RpbGUoKSArIHNjYWxlX2ZpbGxfdmlyaWRpc19jKG5hbWUgPSAibG9nMTAobnVtYmVyIGRlbnNpdHkgXG4gKG5vcm1hbGl6ZWQpKSIpICsgc2NhbGVfeV9yZXZlcnNlKCkgKyBzY2FsZV94X2xvZzEwKCkgKyBnZW9tX2NvbnRvdXIoY29sb3IgPSAiYmxhY2siKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDE2MCwgY29sb3IgPSAiZGFya2dyZWVuIikgKyBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSA4NTAsIGNvbG9yID0gImRhcmtibHVlIikKV0JDb2xvck1hcApgYGAKQXZlcmFnZSBvZiBldmVyeXRoaW5nCgpgYGB7cn0KI21lYW5CZXNlMDQzIDwtIFRvUGxvdCAlPiUgZmlsdGVyKGxiIDw9IDIsIHRpbWUgPT0gIjIwMTctMDEtMTMgMTE6NTE6MzEiKQoKbWVhbkJlc2UlPiUKICAgZ2dwbG90KGFlcyh4ID0gbGIsIHkgPSBkZXB0aCwgZmlsbCA9IGxvZzEwKG5ucGFydGljbGVzKSwgeiA9IGxvZzEwKG5ucGFydGljbGVzKSkpICsgZ2VvbV90aWxlKCkgKyBzY2FsZV9maWxsX3ZpcmlkaXNfYygpICsgc2NhbGVfeV9yZXZlcnNlKCkgKyBzY2FsZV94X2xvZzEwKCkgKyBnZW9tX2NvbnRvdXIoY29sb3IgPSAiYmxhY2siKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDE2MCwgY29sb3IgPSAiZGFya2dyZWVuIikKYGBgCkp1c3QgMDQzCgpgYGB7cn0KbWJHYW0gPC0gbWVhbkJlc2UgJT4lIGdyb3VwX2J5KGRlcHRoKSAgJT4lIG5lc3QoKSAlPiUKICBtdXRhdGUobW9kID0gbWFwKGRhdGEsIH5nYW0obG9nKG5ucGFydGljbGVzKSB+IGxvZyhsYiksIGZhbWlseSA9IGdhdXNzaWFuKCksIGRhdGEgPSAuKSkpICU+JSAKICBtdXRhdGUocHNkID0gbWFwX2RibChtb2QsIH5zdW1tYXJ5KC4pJHAuY29lZmZbMl0pKQpgYGAKCmBgYHtyfQptYkdhbSAlPiUgZ2dwbG90KGFlcyh4ID0gcHNkLCB5ID0gZGVwdGgpKSArIGdlb21fcGF0aCgpICsgc2NhbGVfeV9yZXZlcnNlKCkgKyBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAxNjAsIGNvbG9yID0gImRhcmtncmVlbiIpICsgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gIDg1MCwgY29sb3IgPSAiZGFya2JsdWUiKQpgYGAKCgptYkdhbSA8LSBtZWFuQmVzZTA0MyAlPiUgZ3JvdXBfYnkoZGVwdGgpICAlPiUgbmVzdCgpICU+JQogIG11dGF0ZShtb2QgPSBtYXAoZGF0YSwgfmdhbShsb2cobm5wYXJ0aWNsZXMpIH4gbG9nKGxiKSwgZmFtaWx5ID0gZ2F1c3NpYW4oKSwgZGF0YSA9IC4pKSkgJT4lIAogIG11dGF0ZShwc2QgPSBtYXBfZGJsKG1vZCwgfnN1bW1hcnkoLikkcC5jb2VmZlsyXSkpCgoKYGBge3J9CnBXQlBTRCA8LSBtYkdhbSAlPiUgZ2dwbG90KGFlcyh4ID0gcHNkLCB5ID0gZGVwdGgpKSArIGdlb21fcGF0aCgpICsgc2NhbGVfeV9yZXZlcnNlKCkgICsgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMTYwLCBjb2xvciA9ICJkYXJrZ3JlZW4iKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9ICA4NTAsIGNvbG9yID0gImRhcmtibHVlIikKcFdCUFNECmBgYAoKCiMjIEZpZyA1IFdCCgpiZHMgJT4lIGZpbHRlcihwcm9maWxlID09ICJzdG5fMDQzIiwgZGVwdGggPD0gMjAwMCkgJT4lIGdncGxvdChhZXMoeCA9IHBzZF9nYW0sIHhtaW4gPSBwc2RfZ2FtIC0gcHNkX3NlZyAqIDIsIHhtYXggPSBwc2RfZ2FtICsgcHNkX3NlZyAqIDIsIHkgPSBkZXB0aCkpICsgZ2VvbV9wYXRoKHNpemUgPSAxKSArIHNjYWxlX3lfcmV2ZXJzZSgpICsgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMTc1LCBjb2xvciA9ICJkYXJrZ3JlZW4iKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDk1MCwgY29sb3IgPSAiZGFya2JsdWUiKSArIGdlb21fcmliYm9uKGFscGhhID0gMC4yKSArIGxhYnMoeCA9ICJQU0Qgc2xvcGUiKQoKQWxsIG9mIHRoZW0KCmBgYHtyfQpiZHMgJT4lIGZpbHRlcihwcm9maWxlID09ICJzdG5fMDQzIiwgZGVwdGggPD0gMjAwMCkgJT4lIGdncGxvdChhZXMoeCA9IHBzZF9nYW0sIHhtaW4gPSBwc2RfZ2FtIC0gcHNkX3NlZyAqIDIsIHhtYXggPSBwc2RfZ2FtICsgcHNkX3NlZyAqIDIsIHkgPSBkZXB0aCkpICsgZ2VvbV9wYXRoKHNpemUgPSAxKSArIHNjYWxlX3lfcmV2ZXJzZSgpICsgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMTc1LCBjb2xvciA9ICJkYXJrZ3JlZW4iKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDk1MCwgY29sb3IgPSAiZGFya2JsdWUiKSArIGdlb21fcmliYm9uKGFscGhhID0gMC4yKSArIGxhYnMoeCA9ICJQU0Qgc2xvcGUiKQpgYGAKMDQzIG9ubHkKCmBgYHtyfQpiZHMgJT4lIGZpbHRlcihwcm9maWxlID09ICJzdG5fMDQzIiwgZGVwdGggPD0gMjAwMCwgZGVwdGggPiAxNzUpICU+JSBnZ3Bsb3QoYWVzKHggPSBzbWFsbF9iaW92b2x1bWUsIHkgPSBkZXB0aCkpICsgZ2VvbV9wYXRoKHNpemUgPSAxKSArIHNjYWxlX3lfcmV2ZXJzZSgpICsgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMTc1LCBjb2xvciA9ICJkYXJrZ3JlZW4iKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDk1MCwgY29sb3IgPSAiZGFya2JsdWUiKSArIGdlb21fcG9pbnQoKQpgYGAKCmBgYHtyfQp1YkRmMCA8LSBUb1Bsb3QgJT4lIG11dGF0ZSh1YmlvbWFzcyA9IG5wYXJ0aWNsZXMgKiBsYiBeIGFnX2dsb2JhbCkKdWJEZiA8LSB1YkRmMCAlPiUgZ3JvdXBfYnkodGltZSwgZGVwdGgpICU+JSBzdW1tYXJpemUodWJpb21hc3MgPSBzdW0odWJpb21hc3MpKSAlPiUgdW5ncm91cCAlPiUgZ3JvdXBfYnkoZGVwdGgpCnBob3RpY0Jpb21hc3MgPC0gdWJEZiAlPiUgZmlsdGVyKGRlcHRoIDw9IDE4MCwgZGVwdGggPj0gMTYwKSAlPiUgc3VtbWFyaXplKHViaW9tYXNzID0gbWVhbih1YmlvbWFzcykpICU+JSBwdWxsKHViaW9tYXNzKQp1YkRmIDwtIHViRGYgJT4lIG11dGF0ZShuYmlvbWFzcyA9IHViaW9tYXNzL3Bob3RpY0Jpb21hc3MpCnViRGYgJT4lIGdncGxvdChhZXMoeCA9IG5iaW9tYXNzLCB5ID0gZGVwdGggLCBncm91cCA9IHRpbWUsIGNvbCA9IHRpbWUpKSArIGdlb21fcGF0aCgpICsgc2NhbGVfeV9yZXZlcnNlKCkgKyBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYygwLDEpKQpgYGAKCgogCmBgYHtyfQp1YkRmIDwtIFRvUGxvdCAlPiUgbXV0YXRlKHViaW9tYXNzID0gbnBhcnRpY2xlcyAqIGxiIF4gYWdfZ2xvYmFsKSAlPiUgZ3JvdXBfYnkodGltZSwgZGVwdGgpICU+JSBzdW1tYXJpemUodWJpb21hc3MgPSBzdW0odWJpb21hc3MpKSAlPiUgdW5ncm91cCAlPiUgZ3JvdXBfYnkoZGVwdGgpICAlPiUgc3VtbWFyaXNlKHViaW9tYXNzID0gbWVhbih1YmlvbWFzcykpCnBob3RpY0Jpb21hc3MgPC0gdWJEZiAlPiUgZmlsdGVyKGRlcHRoIDw9IDE4MCwgZGVwdGggPj0gMTYwKSAlPiUgc3VtbWFyaXplKHViaW9tYXNzID0gbWVhbih1YmlvbWFzcykpICU+JSBwdWxsKHViaW9tYXNzKQp1YkRmIDwtIHViRGYgJT4lIG11dGF0ZShuYmlvbWFzcyA9IHViaW9tYXNzL3Bob3RpY0Jpb21hc3MpCnViRGYgJT4lIGdncGxvdChhZXMoeCA9IG5iaW9tYXNzLCB5ID0gZGVwdGgpKSArIGdlb21fcGF0aCgpICsgc2NhbGVfeV9yZXZlcnNlKCkgKyBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYygwLDEpKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDE3NSwgY29sb3IgPSAiZGFya2dyZWVuIikKYGBgCgoKIyMjIFNtYWxsIHBhcnRpY2xlcyBiaW9tYXNzCgpgYGB7cn0KUHViRGYgPC0gVG9QbG90ICU+JSBtdXRhdGUodWJpb21hc3MgPSBucGFydGljbGVzICogbGIgXiBhZ19nbG9iYWwpICU+JSBmaWx0ZXIobGIgPCAwLjUpICU+JSBncm91cF9ieSh0aW1lLCBkZXB0aCkgJT4lIHN1bW1hcml6ZSh1YmlvbWFzcyA9IHN1bSh1YmlvbWFzcykpICU+JSB1bmdyb3VwICU+JSBncm91cF9ieShkZXB0aCkgICU+JSBzdW1tYXJpc2UodWJpb21hc3MgPSBtZWFuKHViaW9tYXNzKSkKcGhvdGljQmlvbWFzcyA8LSBQdWJEZiAlPiUgZmlsdGVyKGRlcHRoIDw9IDE2NSwgZGVwdGggPj0gMTU1KSAlPiUgc3VtbWFyaXplKHViaW9tYXNzID0gbWVhbih1YmlvbWFzcykpICU+JSBwdWxsKHViaW9tYXNzKQpQdWJEZiA8LSBQdWJEZiAlPiUgbXV0YXRlKG5iaW9tYXNzID0gdWJpb21hc3MvcGhvdGljQmlvbWFzcykKcFdCUyA8LSBQdWJEZiAlPiUgZ2dwbG90KGFlcyh4ID0gbmJpb21hc3MsIHkgPSBkZXB0aCkpICsgZ2VvbV9wYXRoKCkgKyBzY2FsZV95X3JldmVyc2UoKSArIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKDAsMS4yKSkgKyBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAxNjAsIGNvbG9yID0gImRhcmtncmVlbiIpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMSwgY29sb3IgPSAiZ3JheTUwIikgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwLCBjb2xvciA9ICJncmF5NTAiKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDg1MCwgY29sb3IgPSAiZGFya2JsdWUiKSArIGxhYnMoIHggPSAiU21hbGwgcGFydGljbGUgbWFzcyAobm9ybS4pIikKcFdCUwpgYGAKCmBgYHtyfQpMdWJEZiA8LSBUb1Bsb3QgJT4lIG11dGF0ZSh1YmlvbWFzcyA9IG5wYXJ0aWNsZXMgKiBsYiBeIGFnX2dsb2JhbCkgJT4lIGZpbHRlcihsYiA+PSAwLjUpICU+JSBncm91cF9ieSh0aW1lLCBkZXB0aCkgJT4lIHN1bW1hcml6ZSh1YmlvbWFzcyA9IHN1bSh1YmlvbWFzcykpICU+JSB1bmdyb3VwICU+JSBncm91cF9ieShkZXB0aCkgICU+JSBzdW1tYXJpc2UodWJpb21hc3MgPSBtZWFuKHViaW9tYXNzKSkKcGhvdGljQmlvbWFzcyA8LSBMdWJEZiAlPiUgZmlsdGVyKGRlcHRoIDw9IDE2NSwgZGVwdGggPj0xNTUpICU+JSBzdW1tYXJpemUodWJpb21hc3MgPSBtZWFuKHViaW9tYXNzKSkgJT4lIHB1bGwodWJpb21hc3MpCkx1YkRmIDwtIEx1YkRmICU+JSBtdXRhdGUobmJpb21hc3MgPSB1YmlvbWFzcy9waG90aWNCaW9tYXNzKQpwV0JMIDwtIEx1YkRmICU+JSBnZ3Bsb3QoYWVzKHggPSBuYmlvbWFzcywgeSA9IGRlcHRoKSkgKyBnZW9tX3BhdGgoKSArIHNjYWxlX3lfcmV2ZXJzZSgpICsgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoMCwxKSkgKyBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAxNjAsIGNvbG9yID0gImRhcmtncmVlbiIpICsgbGFicyggeCA9ICJMYXJnZSBwYXJ0aWNsZSBtYXNzIChub3JtLikiKSArIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDEsIGNvbG9yID0gImdyYXk1MCIpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCwgY29sb3IgPSAiZ3JheTUwIikgKyBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSA4NTAsIGNvbG9yID0gImRhcmtibHVlIikKcFdCTApgYGAKCkZvciB0b20gYW5kIGRhbmllbGxlCmBgYHtyfQpXQkNvbG9yTWFwCnBXQlBTRApwV0JTCnBXQkwKYGBgCgpgYGB7ciwgZmlnLndpZHRoID0gMTAsIGZpZy5oZWlnaHQ9M30KV0JGaWc1IDwtIHBsb3RfZ3JpZChwV0JQU0QsIHBXQlMscFdCTCwgbnJvdyA9IDEsIGxhYmVscyA9IGMoIkIiLCAiQyIsICJEIikpCldCRmlnNQpgYGAKCmBgYHtyIGZpZy5oZWlnaHQgPSA2LCBmaWcud2lkdGggPSA4fQpXQmNvbWJpbmVkIDwtIHBsb3RfZ3JpZChXQkNvbG9yTWFwICsgdGhlbWUocGxvdC5tYXJnaW4gPSB1bml0KGMoMCwzLDAsIDMpLCAiY20iKSksIFdCRmlnNSwgbmNvbCA9IDEsIGxhYmVscyA9IGMoIkEiLCAiIikpCldCY29tYmluZWQKCmdnc2F2ZSgiZmlndXJlcy9XQk1vZGVsVmFsaWRhdGlvbi5wbmciKQpgYGAKCiMjIFAxNiBGbHV4IAoKYGBge3IgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9NH0Kc2NpZW50aWZpY18xMCA8LSBmdW5jdGlvbih4KSB7cGFyc2UodGV4dD1nc3ViKCJlXFwrKiIsICIgJSolIDEwXiIsIHNjYWxlczo6c2NpZW50aWZpY19mb3JtYXQoKSh4KSkpIH0KI2h0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzEwNzYyMjg3L2hvdy1jYW4taS1mb3JtYXQtYXhpcy1sYWJlbHMtd2l0aC1leHBvbmVudHMtd2l0aC1nZ3Bsb3QyLWFuZC1zY2FsZXMKI2phY29iX21hZ25pdHVkZSA8LSBmdW5jdGlvbih4KXtleHByZXNzaW9uKDEwXnJvdW5kKGxvZzEwKHgpKSl9CgpjYjEwIDwtIGMoJyNhNmNlZTMnLCcjMWY3OGI0JywnI2IyZGY4YScsJyMzM2EwMmMnLCcjZmI5YTk5JywnI2UzMWExYycsJyNmZGJmNmYnLCcjZmY3ZjAwJywnI2NhYjJkNicsJyM2YTNkOWEnKQpwbHRGbHhQMTYgPC0gYmRzICU+JSBmaWx0ZXIocHJvamVjdCA9PSAiUDE2IikgJT4lICNmaWx0ZXIoREZQID4gMSkgJT4lICNmaWx0ZXIocHJvZmlsZSAlaW4lIGMoInN0bl8wNDMiLCAicDE2bl8xMDAiKSkgJT4lCiAgZ2dwbG90KGFlcyh5ID0gZGVwdGgsIHggPSBGbHV4X1Ntb290aCwgZ3JvdXAgPSBmYWN0b3IodGltZSkpKSAgKyBnZW9tX3BvaW50KHNpemUgPSAzLCBzdHJva2UgPSAxKSsKICBnZW9tX3BhdGgoKSArCiAgc2NhbGVfeV9yZXZlcnNlKGxpbWl0cyA9IGMoMTAwMCwgMCkpKwogIHNjYWxlX3hfbG9nMTAobGltaXRzID0gYygzNSwgMTUwKSxicmVha3MgPSBzZXEoZnJvbSA9IDIwLCB0byA9IDE1MCwgYnkgPSAyMCkpICsKICAgc2NhbGVfY29sb3JfZ3JhZGllbnQyKGxvdyA9ICJkYXJrZ3JlZW4iLCBtaWQgPSAiZ3JheTgwIiwgaGlnaCA9ICJwdXJwbGUiLCBtaWRwb2ludCA9IDEwKSArIHNjYWxlX3NoYXBlX21hbnVhbChuYW1lID0gIkRheSBvZiBNb250aCIsIHZhbHVlcyA9IHJlcCgyMToyNSwgMikpICsgCiAgc2NhbGVfZmlsbF9ncmFkaWVudG4obmFtZSA9ICJIb3VyIG9mIERheSIsIGJyZWFrcyA9IGMoMCwgNiwgMTIsIDE4LCAyNCksIGNvbG9ycyA9IGMoImJsYWNrIiwgImJsdWUiLCAid2hpdGUiLCAib3JhbmdlIiwgImJsYWNrIikpICsKICAKbGFicyh4ID0gYnF1b3RlKFNtb290aGVkfkZsdXh+KMK1bW9sfkMvbV4yL2QpKSwgeSA9ICJEZXB0aCAobSkiKSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMjAwLCBjb2xvciA9ICJkYXJrZ3JlZW4iKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgdmp1c3QgPSAuMyksIGxlZ2VuZC5zcGFjaW5nID0gdW5pdCguMSwgImNtIikpCiMgCiMgCiMgCiMgcGx0Rmx4Tm9MZWdlbmQgPC0gcGx0Rmx4ICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQojIHBsdEZseExlZ2VuZCA8LSBnZXRfbGVnZW5kKHBsdEZseCkKIyAKcGx0Rmx4UDE2CiMgI3Bsb3RseTo6Z2dwbG90bHkocGx0MSkKYGBgCgpgYGB7ciBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD00fQpjYjEwIDwtIGMoJyNhNmNlZTMnLCcjMWY3OGI0JywnI2IyZGY4YScsJyMzM2EwMmMnLCcjZmI5YTk5JywnI2UzMWExYycsJyNmZGJmNmYnLCcjZmY3ZjAwJywnI2NhYjJkNicsJyM2YTNkOWEnKQpwbHREZWx0YTNQMTYgPC0gYmRzICU+JSBmaWx0ZXIocHJvamVjdCA9PSAiUDE2IikgJT4lICNmaWx0ZXIoREZQID4gMSkgJT4lICNmaWx0ZXIocHJvZmlsZSAlaW4lIGMoInN0bl8wNDMiLCAicDE2bl8xMDAiKSkgJT4lCiAgZ2dwbG90KGFlcyh5ID0gZGVwdGgsIHggPSBwcmFjbWE6Om50aHJvb3QoREYvRFosIDUpLCBncm91cCA9IGZhY3Rvcih0aW1lKSkpICArIGdlb21fcG9pbnQoc2l6ZSA9IDMsIHN0cm9rZSA9IDEpKwogIGdlb21fcGF0aCgpICsKICBzY2FsZV95X3JldmVyc2UobGltaXRzID0gYygxMDAwLCAwKSkrCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoLTEsIC4xKSwgYnJlYWtzID0gc2VxKGZyb20gPSAtMiwgdG8gPSAuNzUsIGJ5ID0gMC41KSkgKwogICNzY2FsZV94X2xvZzEwKCkgKwogICBzY2FsZV9jb2xvcl9ncmFkaWVudDIobG93ID0gImRhcmtncmVlbiIsIG1pZCA9ICJncmF5ODAiLCBoaWdoID0gInB1cnBsZSIsIG1pZHBvaW50ID0gMTApICsgc2NhbGVfc2hhcGVfbWFudWFsKG5hbWUgPSAiRGF5IG9mIE1vbnRoIiwgdmFsdWVzID0gcmVwKDIxOjI1LCAyKSkgKyAKICBzY2FsZV9maWxsX2dyYWRpZW50bihuYW1lID0gIkhvdXIiLCBicmVha3MgPSBjKDAsIDYsIDEyLCAxOCwgMjQpLCBjb2xvcnMgPSBjKCJibGFjayIsICJibHVlIiwgIndoaXRlIiwgIm9yYW5nZSIsICJibGFjayIpKSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCkgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDIwMCwgY29sb3IgPSAiZGFya2dyZWVuIikrCiAgbGFicyh4ID0gYnF1b3RlKChERi9EWileezEvNX1+KMK1bW9sQy9tXjMvZCleezEvNX0pLCB5ID0gIkRlcHRoIChtKSIpICsgdGhlbWUobGVnZW5kLnBvcyA9ICJub25lIikKICAjbGFicyh4ID0gIihERi9EWikgXiAxLzUgKMK1bW9sIEMvbV4zL2QpIF4gMS81IikKCnBsdERlbHRhM1AxNgojcGxvdGx5OjpnZ3Bsb3RseShwbHQxcG9zKQpgYGAKCmBgYHtyIGZpZy53aWR0aCA9IDYsIGZpZy5oZWlnaHQgPSA0fQpvc21zX3AxNiA8LSBiZHMgJT4lIGZpbHRlcihwcm9qZWN0ID09ICJQMTYiKSAlPiUKICBnZ3Bsb3QoYWVzKHkgPSBkZXB0aCwgeCA9IHByYWNtYTo6bnRocm9vdChvc3BzRFosIDMpLCBncm91cCA9IGZhY3Rvcih0aW1lKSkpICsgZ2VvbV9wb2ludChzaXplID0gMykgKyBnZW9tX3BhdGgoKSArIHNjYWxlX3lfcmV2ZXJzZShsaW1pdHMgPSBjKDEwMDAsIDApKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoLTEsIDEpKSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCkgKyAgIHNjYWxlX3NoYXBlX21hbnVhbChuYW1lID0gIkRheSBvZiBNb250aCIsIHZhbHVlcyA9IHJlcCgyMToyNSwgMikpICsgbGFicyh4ID0gIk9ic2VydmVkIC0gTW9kZWxlZCBTbWFsbCBQYXJ0aWNsZSBGbHV4IFxuIMK1bW9sL21eMy9kYXkiKSArCiAgc2NhbGVfZmlsbF9ncmFkaWVudG4obmFtZSA9ICJIb3VyIG9mIERheSIsIGJyZWFrcyA9IGMoMCwgNiwgMTIsIDE4LCAyNCksIGNvbG9ycyA9IGMoImJsYWNrIiwgImJsdWUiLCAid2hpdGUiLCAib3JhbmdlIiwgImJsYWNrIikpICsgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMTc1LCBjb2xvciA9ICJkYXJrZ3JlZW4iKSAKcGxvdGx5OjpnZ3Bsb3RseShvc21zX3AxNikKI2dnc2F2ZSgiLi5maWd1cmVzL0ZsdXhTaXplU2hpZnQuc3ZnIgoKYGBgCgpgYGB7ciBmaWcud2lkdGggPSA4LCBmaWcuaGVpZ2h0PTh9CnBsb3RfZ3JpZCgKICBwbHRGbHhQMTYsCiAgcGx0RGVsdGEzUDE2LAogIG9zbXNfcDE2CikKCmdnc2F2ZSgiZmlndXJlcy9QMTZGbHV4UmVsYXRlLnN2ZyIpCmdnc2F2ZSgiZmlndXJlcy9QMTZGbHV4UmVsYXRlLnBuZyIpCmBgYAoKIyBGbHV4IGF0dGVudWF0aW9uIGV4YW1wbGUKCmBgYHtyfQpzb3VyY2UoIk1vZGVsU3R1ZmYuUiIpCmBgYAoKCmBgYHtyfQpzY2FuX2Zvcl9leGFtcGxlIDwtIGJkcyAlPiUgZmlsdGVyKHByb2plY3QgPT0gIkVUTlAiLCBkZXB0aCA8IDUwMCwgZGVwdGggPiAyMDApICU+JSBzZWxlY3QocHJvZmlsZSwgZGVwdGgsIERGUCwgdXNlX3RoaXNfREZQLCBvc3BzRFopCgpsb2Nfc3RhdGlvbiA9ICJzdG5fMDM2Igpsb2NfZGVwdGggPSAyMjUKbG9jX3ByZXZfZGVwdGggPSBsb2NfZGVwdGggLSA1MAoKbG9jX0RGUCA8LSBiZHMgJT4lIGZpbHRlcihwcm9maWxlID09IGxvY19zdGF0aW9uLCBkZXB0aCAlaW4lIGMoMjc1KSkgJT4lIHB1bGwoREZQKQpsb2NfdXNlX0RGUCA8LSBiZHMgJT4lIGZpbHRlcihwcm9maWxlID09IGxvY19zdGF0aW9uLCBkZXB0aCAlaW4lIGMoMjc1KSkgJT4lIHB1bGwodXNlX3RoaXNfREZQKQpmb3Jfc2luZ2xlX2Rpc2FnIDwtIGJlcyAlPiUgZmlsdGVyKHByb2ZpbGUgPT0gbG9jX3N0YXRpb24sIGRlcHRoICVpbiUgYygyMjUsIDI3NSkpICU+JSBzZWxlY3QoZGVwdGgsIGxiLCBubnBfc21vb3RoKSAlPiUKICBtdXRhdGUoZGVwdGggPSByZWNvZGUoZGVwdGgsIGAyMjVgID0gIlNoYWxsb3ciLCBgMjc1YCA9ICJEZWVwIikpICU+JQogIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBkZXB0aCwgdmFsdWVzX2Zyb20gPSBubnBfc21vb3RoKSAKCndpdGhfZGlzYWcgPC0gZm9yX3NpbmdsZV9kaXNhZyAlPiUKICBtdXRhdGUoUHJlZGljdGVkX0RlZXAgPSByZW1pbl9zbW9vdGhfc2h1ZmZsZShTaGFsbG93LCBsb2NfdXNlX0RGUCkpIAojcmVtaW5fc21vb3RoX3NodWZmbGUoZm9yX3NpbmdsZV9kaXNhZyRTaGFsbG93LGxvY191c2VfREZQKQoKZm9yX3Bsb3RfZGlzYWcgPC0gd2l0aF9kaXNhZyAlPiUgcGl2b3RfbG9uZ2VyKGNvbHMgPSAtbGIpICU+JSBmaWx0ZXIobGIgPD0gMC41KSAlPiUKICBtdXRhdGUobmFtZSA9IGZhY3RvcihuYW1lLCBsZXZlbHMgPSBjKCJTaGFsbG93IiwgIkRlZXAiLCAiUHJlZGljdGVkX0RlZXAiKSkpICU+JQogIG11dGF0ZShuYW1lID0gcmVjb2RlX2ZhY3RvcihuYW1lLCBTaGFsbG93ID0gIlNoYWxsb3cgKDI1MG0pIiwgRGVlcCA9ICJEZWVwICgyNzVtKSIsIFByZWRpY3RlZF9EZWVwID0gIlByZWRpY3RlZCBEZWVwICgyNzVtKSIpKQoKZm9yX3Bsb3RfZGlzYWcgJT4lIGdncGxvdChhZXMoeCA9IGxiLCB5ID0gdmFsdWUsIHNoYXBlID0gbmFtZSkpICsgZ2VvbV9wb2ludCgpICsgc2NhbGVfeF9sb2cxMCgpICsgc2NhbGVfeV9sb2cxMCgpICsgc2NhbGVfc2hhcGVfbWFudWFsKHZhbHVlcyA9IGMoMSwgNiwgMykpICsgdGhlbWUobGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpKSArIGxhYnMoeCA9ICJQYXJ0aWNsZSBTaXplIChtbSkiLCB5ID0gIk5vcm1hbGl6ZWQgUGFydGljbGUgQWJ1bmRhbmNlICgjL0wvbW0pIikKCmdnc2F2ZSgiZmlndXJlcy9EaXNhZ0V4YW1wbGUucG5nIikKZ2dzYXZlKCJmaWd1cmVzL0Rpc2FnRXhhbXBsZS5zdmciKQpgYGAKCgojIyBFSzYwCgpgYGB7cn0KZGF0YUJpbm5lZCA8LSByZWFkX2NzdigiZGF0YS9iYWNrc2NhdHRlcl90YWJsZV9nbzcuY3N2IikKYGBgCgpgYGB7cn0KZGF0YUJpbm5lZF8wMSA8LSBkYXRhQmlubmVkICU+JQogIG11dGF0ZSh0aW1lTWV4ID0gd2l0aF90eih0aW1lX2JpbiwgdHpvbmUgPSAiVVMvQ2VudHJhbCIpICkKYGBgCgpgYGB7cn0Kc3RhcnREYXkgPC0gZGF0YUJpbm5lZF8wMSR0aW1lTWV4ICU+JSBuYS5vbWl0ICU+JSBtaW4gJT4lIGZsb29yX2RhdGUodW5pdCA9ICJkYXlzIikKZW5kRGF5IDwtIGRhdGFCaW5uZWRfMDEkdGltZU1leCAlPiUgbmEub21pdCAlPiUgbWF4ICU+JSBjZWlsaW5nX2RhdGUodW5pdCA9ICJkYXlzIikKdGltZUJyZWFrcyA8LSBzZXEoZnJvbSA9IHN0YXJ0RGF5LCB0byA9IGVuZERheSwgYnkgPSAiMTIgaG91cnMiKQp0aW1lTGFiZWxzIDwtIGZvcm1hdCh0aW1lQnJlYWtzKQpgYGAKCgpgYGB7cn0KcGxvdExldHRlcnMgPC0gdHJpYmJsZSgKICB+bGV0dGVyLCB+ZGVwdGhfYmluLCB+dGltZU1leCwKICAiQSIsIDM1MCwgYXMuUE9TSVhjdCgiMjAxNy0wMS0wNyAxMzowMDowMCIpLAogICJCIiwgMjAwLCBhcy5QT1NJWGN0KCIyMDE3LTAxLTA5IDIzOjAwOjAwIiksCiAgIkMiLCAxNTAsIGFzLlBPU0lYY3QoIjIwMTctMDEtMDggMTM6MDA6MDAiKSwKICAiRCIsIDYyNSwgYXMuUE9TSVhjdCgiMjAxNy0wMS0xMiAwNzowMDowMCIpLAogICJFIiwgNzUwLCBhcy5QT1NJWGN0KCIyMDE3LTAxLTEwIDAyOjAwOjAwIikKICAKKQoKbGlicmFyeShzaGFkb3d0ZXh0KQpwbG90MThrIDwtIGRhdGFCaW5uZWRfMDEgJT4lIGZpbHRlcihmcmVxdWVuY3kgPT0gMTgwMDApICU+JSBnZ3Bsb3QoYWVzKHggPSB0aW1lTWV4LCB5ID0gZGVwdGhfYmluLCBmaWxsID0gdmFsdWUpKSArIGdlb21fdGlsZSgpICsgc2NhbGVfeV9yZXZlcnNlKCkgKyBzY2FsZV9maWxsX3ZpcmlkaXNfYyhsaW1pdHMgPSBjKC0xNjUsIC03NSksIG9vYiA9IHNjYWxlczo6c3F1aXNoKSArCiAgc2NhbGVfeF9kYXRldGltZShicmVha3MgPSB0aW1lQnJlYWtzLCBkYXRlX2xhYmVscyA9ICIlZDo6JUgiKSArIGxhYnMoeCA9ICJkYXk6OmhvdXIiLCB5ID0gImRlcHRoIChtKSIsIGZpbGwgPSAiYmFja3NjYXR0ZXIgKGRCKSIpICsgdGhlbWVfYncoKSArIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIHZqdXN0ID0gMC41KSkgKyBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAxNjAsIGNvbG9yID0gImRhcmtncmVlbiIpICsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSA4NTAsIGNvbG9yID0gImRhcmtibHVlIikgKwogIGdlb21fc2hhZG93dGV4dChkYXRhID0gcGxvdExldHRlcnMsIGFlcyh4ID0gdGltZU1leCAtIDEyICogNjBeMiwgeSA9IGRlcHRoX2JpbiwgbGFiZWwgPSBsZXR0ZXIpLCAgaW5oZXJpdC5hZXMgPSBGQUxTRSwgc2l6ZSA9IDYsIGJnLmNvbG9yID0gIndoaXRlIiwgY29sb3IgPSAiYmxhY2siKSArCiAgZ2VvbV9zZWdtZW50KGRhdGEgPSBwbG90TGV0dGVycywgaW5oZXJpdC5hZXMgPSBGQUxTRSwgYWVzKHggPSB0aW1lTWV4IC0gOSAqIDYwXjIsIHhlbmQgPSB0aW1lTWV4LCB5ID0gZGVwdGhfYmluLCB5ZW5kID0gZGVwdGhfYmluKSwgYXJyb3cgPSBhcnJvdyhsZW5ndGggPSB1bml0KDAuMDMsICJucGMiKSksIGNvbG9yID0gIndoaXRlIiwgc2l6ZSA9IDEuNSkgKyAKICBnZW9tX3NlZ21lbnQoZGF0YSA9IHBsb3RMZXR0ZXJzLCBpbmhlcml0LmFlcyA9IEZBTFNFLCBhZXMoeCA9IHRpbWVNZXggLSA5ICogNjBeMiwgeGVuZCA9IHRpbWVNZXgsIHkgPSBkZXB0aF9iaW4sIHllbmQgPSBkZXB0aF9iaW4pLCBhcnJvdyA9IGFycm93KGxlbmd0aCA9IHVuaXQoMC4wMywgIm5wYyIpKSkKcGxvdDE4awoKI2dnc2F2ZSgiZmlndXJlcy9zdGF0aW9uUDJfRUs2MF8xOGtPbmx5LnBuZyIpCmBgYAoKYGBge3J9CnBsb3RMZXR0ZXJzIDwtIHRyaWJibGUoCiAgfmxldHRlciwgfmRlcHRoX2JpbiwgfnRpbWVNZXgsCiAgIkEiLCAzMDAsIGFzLlBPU0lYY3QoIjIwMTctMDEtMDcgMTM6MDA6MDAiKSwKICAiQiIsIDIwMCwgYXMuUE9TSVhjdCgiMjAxNy0wMS0wOSAyMzowMDowMCIpLAogICJDIiwgMTUwLCBhcy5QT1NJWGN0KCIyMDE3LTAxLTA4IDEzOjAwOjAwIiksCiAgIkQiLCA2MjUsIGFzLlBPU0lYY3QoIjIwMTctMDEtMTIgMDc6MDA6MDAiKSwKICAiRSIsIDc1MCwgYXMuUE9TSVhjdCgiMjAxNy0wMS0xMCAwMjowMDowMCIpCiAgCikKCmxpYnJhcnkoc2hhZG93dGV4dCkKcGxvdDM4ayA8LSBkYXRhQmlubmVkXzAxICU+JSBmaWx0ZXIoZnJlcXVlbmN5ID09IDM4MDAwKSAlPiUgZ2dwbG90KGFlcyh4ID0gdGltZU1leCwgeSA9IGRlcHRoX2JpbiwgZmlsbCA9IHZhbHVlKSkgKyBnZW9tX3RpbGUoKSArIHNjYWxlX3lfcmV2ZXJzZSgpICsgc2NhbGVfZmlsbF92aXJpZGlzX2MobGltaXRzID0gYygtMTY1LCAtOTUpLCBvb2IgPSBzY2FsZXM6OnNxdWlzaCkgKwogIHNjYWxlX3hfZGF0ZXRpbWUoYnJlYWtzID0gdGltZUJyZWFrcywgZGF0ZV9sYWJlbHMgPSAiJWQ6OiVIIikgKyBsYWJzKHggPSAiRGF5OjpIb3VyIiwgeSA9ICJEZXB0aCAobSkiLCBmaWxsID0gIkJhY2tzY2F0dGVyIChkQikiKSArIHRoZW1lX2J3KCkgICsgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMTYwLCBjb2xvciA9ICJkYXJrZ3JlZW4iKSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gODUwLCBjb2xvciA9ICJkYXJrYmx1ZSIpICsKICBnZW9tX3NoYWRvd3RleHQoZGF0YSA9IHBsb3RMZXR0ZXJzWzE6MixdLCBhZXMoeCA9IHRpbWVNZXggLSAxMiAqIDYwXjIsIHkgPSBkZXB0aF9iaW4sIGxhYmVsID0gbGV0dGVyKSwgIGluaGVyaXQuYWVzID0gRkFMU0UsIHNpemUgPSA2LCBiZy5jb2xvciA9ICJ3aGl0ZSIsIGNvbG9yID0gImJsYWNrIikgKwogIGdlb21fc2VnbWVudChkYXRhID0gcGxvdExldHRlcnNbMToyLF0sIGluaGVyaXQuYWVzID0gRkFMU0UsIGFlcyh4ID0gdGltZU1leCAtIDkgKiA2MF4yLCB4ZW5kID0gdGltZU1leCwgeSA9IGRlcHRoX2JpbiwgeWVuZCA9IGRlcHRoX2JpbiksIGFycm93ID0gYXJyb3cobGVuZ3RoID0gdW5pdCgwLjAzLCAibnBjIikpLCBjb2xvciA9ICJ3aGl0ZSIsIHNpemUgPSAxLjUpICsgCiAgZ2VvbV9zZWdtZW50KGRhdGEgPSBwbG90TGV0dGVyc1sxOjIsXSwgaW5oZXJpdC5hZXMgPSBGQUxTRSwgYWVzKHggPSB0aW1lTWV4IC0gOSAqIDYwXjIsIHhlbmQgPSB0aW1lTWV4LCB5ID0gZGVwdGhfYmluLCB5ZW5kID0gZGVwdGhfYmluKSwgYXJyb3cgPSBhcnJvdyhsZW5ndGggPSB1bml0KDAuMDMsICJucGMiKSkpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIsYW5nbGUgPSA5MCwgdmp1c3QgPSAwLjUpLAogICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICAgICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQpLAogICAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQpCiAgICAgICAgKQpwbG90MzhrCgpnZ3NhdmUoImZpZ3VyZXMvc3RhdGlvblAyX0VLNjBfMzhrT25seS5wbmciKQpgYGAKCgpgYGB7cn0KcGxvdDE4ayArIHNjYWxlX3lfcmV2ZXJzZShsaW1pdHMgPSBjKDUwMCwgMjAwKSkKYGBgCgpgYGB7cn0KcGxvdDIwMGsgPC0gZGF0YUJpbm5lZF8wMSAlPiUgZmlsdGVyKGZyZXF1ZW5jeSA9PSAyMDAwMDApICU+JSBnZ3Bsb3QoYWVzKHggPSB0aW1lTWV4LCB5ID0gZGVwdGhfYmluLCBmaWxsID0gdmFsdWUpKSArIGdlb21fdGlsZSgpICsgc2NhbGVfeV9yZXZlcnNlKCkgKyBzY2FsZV9maWxsX3ZpcmlkaXNfYyhsaW1pdHMgPSBjKC0xNjUsIC0xNTUpLCBvb2IgPSBzY2FsZXM6OnNxdWlzaCkgKwogIHNjYWxlX3hfZGF0ZXRpbWUoYnJlYWtzID0gdGltZUJyZWFrcywgZGF0ZV9sYWJlbHMgPSAiJWQ6OiVIIikgKyBsYWJzKHggPSAiZGF5Ojpob3VyIiwgeSA9ICJkZXB0aCAobSkiLCBmaWxsID0gImJhY2tzY2F0dGVyIChkQikiKSArIHRoZW1lX2J3KCkgKyB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCB2anVzdCA9IDAuNSkpICsgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMTYwLCBjb2xvciA9ICJkYXJrZ3JlZW4iKSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gODUwLCBjb2xvciA9ICJkYXJrYmx1ZSIpCnBsb3QyMDBrCmBgYAoKYGBge3IgZmlnLmhlaWdodD0yMCwgZmlnLndpZHRoID0gOH0KZGF0YUJpbm5lZF8wMSAlPiUgZ2dwbG90KGFlcyh4ID0gdGltZU1leCwgeSA9IGRlcHRoX2JpbiwgZmlsbCA9IHZhbHVlKSkgKyBnZW9tX3RpbGUoKSArIHNjYWxlX3lfcmV2ZXJzZSgpICsgc2NhbGVfZmlsbF92aXJpZGlzX2MobGltaXRzID0gYygtMTY1LCAtNzUpLCBvb2IgPSBzY2FsZXM6OnNxdWlzaCkgKwogIHNjYWxlX3hfZGF0ZXRpbWUoYnJlYWtzID0gdGltZUJyZWFrcywgZGF0ZV9sYWJlbHMgPSAiJWQ6OiVIIikgKyBsYWJzKHggPSAiZGF5Ojpob3VyIiwgeSA9ICJEZXB0aCAobSkiLCBmaWxsID0gImJhY2tzY2F0dGVyIChkQikiKSArIHRoZW1lX2J3KCkgKyB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCB2anVzdCA9IDAuNSkpICsKICAKICAKICBmYWNldF93cmFwKH5mcmVxdWVuY3ksIG5jb2wgPSAxKQoKI2dnc2F2ZSgiZmlndXJlcy9zdGF0aW9uUDJfRUs2MF9nbzcuc3ZnIiwgd2lkdGggPSA0LCBoZWlnaHQgPSAxMCkKZ2dzYXZlKCJmaWd1cmVzL3N0YXRpb25QMl9FSzYwX2dvNy5wbmciLCB3aWR0aCA9IDYsIGhlaWdodCA9IDEwKQpgYGA=